肃清取缔¶
提高命中率的最有效方法之一是增加对象的生存时间(TTL)。但是,正如你所意识到的,在这个推特时代,提供过时的内容对商业不利。
解决方案是当有新的内容可用时通知Varnish。这可以通过三种机制来实现。HTTP清除、禁止和强制缓存未命中。首先,让我们来看看HTTP清除。
HTTP清除¶
A purge 是从缓存中选择一个对象并将其连同其变体一起丢弃时发生的情况。通常使用以下方法通过HTTP调用清除 PURGE 。
HTTP清除类似于HTTP GET请求,只是 method 是 PURGE 。实际上,您可以随心所欲地将该方法命名为任何名称,但大多数人将其称为清除。例如,Squid支持相同的机制。为了支持在Varnish中清除,您需要具备以下VCL:
acl purge {
"localhost";
"192.168.55.0"/24;
}
sub vcl_recv {
# allow PURGE from localhost and 192.168.55...
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Not allowed."));
}
return (purge);
}
}
如你所见,我们使用了一个新的动作--返回(清除)。这将结束vclrecv的执行并跳转到vclhash。这就像我们处理常规请求一样。当vclhash调用返回(查找)时,Varnish将清除对象,然后调用vclPurge。在这里,您可以选择添加您希望Varnish在清除对象后采取的任何特定操作。
因此,为了让Example.com使他们的首页无效,他们会像这样呼叫Varnish::
PURGE / HTTP/1.0
Host: example.com
然后瓦尼什就会丢弃头版。这将删除由Variable定义的所有变体。
禁令¶
还有另一种方法可以使内容无效:禁令。您可以将禁令看作是对缓存中已有对象的一种筛选。你 ban
从您的缓存中提供某些内容。您可以禁止基于我们拥有的任何元数据的内容。禁令仅适用于缓存中已有的对象,不会阻止新内容进入缓存或提供服务。
对BANS的支持内置于Varnish中,并在CLI界面中提供。要禁止属于Example.com上的每个PNG对象,请从Shell发出以下命令:
varnishadm ban req.http.host == example.com '&&' req.url '~' '\\.png$'
看见 Bool BAN(字符串) 有关BAN表达式语法的详细信息,请参阅。特别要注意的是,在上面给出的示例中,从Shell执行时需要使用引号,而Varnish cli接口需要转义正则表达式中的反斜杠。
当我们命中缓存中的对象时,但在我们交付它之前,会检查禁令。 An object is only checked against newer bans 。
禁令只与以下内容匹配 obj.* 也由名为 ban lurker 。这个 ban lurker 将遍历堆并尝试匹配对象,并将驱逐匹配的对象。有多咄咄逼人 ban lurker 可以通过参数‘BAN_LURKER_SLEEP’来控制。这个 ban lurker 可以通过将‘BAN_LURKER_SLEEP’设置为0来禁用。
比缓存中最早的对象更早的禁令将被丢弃,而不进行评估。如果您有很多很少访问的具有长TTL的对象,您可能会积累大量的禁止。这可能会影响CPU使用率,从而影响性能。
您还可以通过HTTP向Varnish添加禁令。要做到这一点,需要一点VCL::
import std;
sub vcl_recv {
if (req.method == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return(synth(403, "Not allowed."));
}
if (std.ban("req.http.host == " + req.http.host +
" && req.url == " + req.url)) {
return(synth(200, "Ban added"));
} else {
# return ban error in 400 response
return(synth(400, std.ban_error()));
}
}
}
此VCL节使Varnish能够处理 HTTP BAN 方法,添加对URL的禁令,包括宿主部分。
这个 ban lurker 可以帮助您将禁止列表的大小保持在可管理的范围内,因此我们建议您避免使用 req.* 在禁令中,因为请求对象在 ban lurker 线。
您可以使用以下模板编写 ban lurker 友好禁令::
import std;
sub vcl_backend_response {
set beresp.http.url = bereq.url;
}
sub vcl_deliver {
unset resp.http.url; # Optional
}
sub vcl_recv {
if (req.method == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return(synth(403, "Not allowed."));
}
# Assumes req.url is a regex. This might be a bit too simple
if (std.ban("obj.http.url ~ " + req.url)) {
return(synth(200, "Ban added"));
} else {
# return ban error in 400 response
return(synth(400, std.ban_error()));
}
}
}
要检查当前的禁令列表,请发出 ban.list
CLI中的命令。这将生成当前所有禁令的状态:
0xb75096d0 1318329475.377475 10 obj.http.url ~ test
0xb7509610 1318329470.785875 20G obj.http.url ~ test
禁令列表包含禁令的ID,即禁令进入禁令列表的时间戳。在禁令列表中达到这一点的对象的计数,如果禁令不再有效,则可以选择在其后面加上表示“已消失”的“G”。最后,列出了BAN的表述。请注意,持续时间不一定以最初给定的单位表示,例如 7d
将会变成 1w
。
如果该禁令是重复的禁令,则可以将其标记为“已取消”,但出于优化的目的,该禁令仍保留在列表中。
强制缓存未命中¶
使对象无效的最后一种方法是一个方法,它允许您通过强制 hash miss 只有一个请求。如果将‘req.hash_Always_Misse’设置为TRUE,Varnish将丢失缓存中的当前对象,从而强制从后端获取。这又可以将新获取的对象添加到缓存中,从而覆盖当前对象。旧对象将一直留在高速缓存中,直到TTL到期或通过某些其他方式将其驱逐。