Varnish 5.1中的更改¶
我们在Varnish 5.1中有几个有趣的新功能,我们有很多小的改进和错误修复,自从Varnish 5.0以来,我们总共提交了大约750次,所以这只是其中的一些亮点。
Varnish 5.1中最大的变化可能是Varnish的几个非常重要的贡献者已经换了工作,因此不再是Varnish项目的积极贡献者。
佩尔·布尔是第一批意识到瓦尼什不仅仅是几家北欧报纸的节目的人之一,他创办了瓦尼什软件公司,这是瓦尼什项目的主要赞助商之一。
Lasse Karstensen被PER捆绑到Varnish Software,除了他的其他职责外,我们现在工作的11年中的大部分时间里,他都负责项目的系统管理和发布工程。
Per&Lasse:谢谢还不够,我们祝你未来一切顺利!
启动CLI命令文件¶
在varnishd中添加新的‘-i cli_file’选项将使使用Varnish 5.0中引入的VCL标签更加实用。
文件中的CLI命令将在工作进程启动之前执行,因此它可能包含::
vcl.load panic /etc/varnish_panic.vcl
vcl.load siteA0 /etc/varnish_siteA.vcl
vcl.load siteB0 /etc/varnish_siteB.vcl
vcl.load siteC0 /etc/varnish_siteC.vcl
vcl.label siteA siteA0
vcl.label siteB siteB0
vcl.label siteC siteC0
vcl.load main /etc/varnish_main.vcl
vcl.use main
如果文件中的命令以‘-’为前缀,则失败不会中止启动。
与此更改相关的是,我们对参数检查进行了重新排序,以便更一致地报告参数问题。
如果您还没有听说过它们,标记VCL程序允许您扩展到Main::VCL_recv{}中的其他VCL,在上面的示例中它可能类似于::
sub vcl_recv {
if (req.http.host ~ "asite.example.com$") {
return(vcl(siteA));
}
if (req.http.host ~ "bsite.example.com$") {
return(vcl(siteB));
}
if (req.http.host ~ "csite.example.com$") {
return(vcl(siteC));
}
// Main site processing ...
}
通用VCL返回(失败)¶
现在有可能 return(fail)
在VCL的任何地方,包括VMOD内部。这将导致VCL处理立即终止。
除了……之外 return(fail)
,此机制将用于处理所有故障情况,而无需安全的回退,例如工作空间耗尽、头文件过多等。(这是一项正在进行的工作,在我们完成之前有很多代码需要检查。)
在……里面 vcl_init{}
失败会导致 vcl.load
失败了,这对这个子例程来说并不新鲜。
任何客户端VCL方法出现故障 (vcl_recv{}
, vcl_hash{}
.) except vcl_synth{}
,将请求发送到 vcl_synth{}
带503,原因是“VCL失败”。
后端出现故障 (vcl_backend_*{}
)会导致提取失败。
(VMOD编写器应使用新的 VRT_fail(ctx, format_string, ...)
记录SLT_VCL_ERROR记录的函数。)
支持HTTP/2的进展¶
Http/2支持比5.0更好,在我们自己的Varnish-cache.org网站上现在已经启用并很好地存活了下来,但仍然缺少一些东西,最明显的是Windows和优先级,这可能会对更复杂的网站造成致命的影响。
我们希望在2017年秋季发布的Varnish-缓存中提供对HTTP/2的支持,但这需要测试和来自实际应用程序的反馈。
因此,如果您有机会测试我们的HTTP/2代码,请务必这样做,如果有任何崩溃、错误或其他问题,请向我们报告。
要启用HTTP/2,您需要 param.set feature +http2
但由于网络政治的原因,如果你在Varnish前面有一个用ALPN通告HTTP2的SSL代理,你将只能看到HTTP/2流量。
对于Hitch SSL代理,添加参数 --alpn-protos="h2,http/1.1"
击球传球又回来了¶
如中所暗示的 Varnish 5.0中的更改 ,我们恢复了调用VCL中旧的一击即传功能的可能性。对无法缓存的内容的处理仍然是默认的,这是5.0版中的新功能,我们称之为“命中未命中”。现在你可以选择击球传球 return(pass(DURATION))
从… vcl_backend_response
,将参数中的命中传球状态的持续时间设置为 pass
。例如: return(pass(120s))
。
简单地说:当 beresp.uncacheable
设置为 true
在……里面 vcl_backend_response
,Varnish使用缓存中的最小对象将其记下来,并在下一次查找同一对象时再次找到该信息。本质上,缓存用于记住上一个后端响应是不可缓存的。在这种情况下,Varnish将继续执行缓存未命中操作,因此响应可能会在后续请求中变为可缓存。不同之处在于,当响应被标记为不可缓存时,Varnish不会像对普通未命中那样执行请求合并。对于普通的未命中,当同时存在针对同一对象的待决请求时,一次只执行一个获取,因为响应可能被缓存,在这种情况下,缓存的响应可能用于剩余的请求。但这不适用于“命中未命中”对象,因为已知它们在上一次提取时是不可缓存的。
builtin.vcl
集合 beresp.uncacheable
至 true
当后端响应满足指示不应缓存它的多个条件时,例如,如果TTL已被确定为0(可能是由于 Cache-Control
标头),或者如果 Set-Cookie
响应中存在标头。因此,命中未命中是不可缓存的后端响应的默认设置。
这样做的一个后果是,在默认情况下,对不可缓存响应的提取不能是有条件的。也就是说,后端请求可能不包括报头 If-Modified-Since
或 If-None-Match
,这可能会导致后端返回没有响应正文的状态“304 Not Modify”。由于对缓存未命中的响应可能会被缓存,因此必须有一个正文来缓存,对于命中未命中也是如此。如果客户端请求中存在这两个标头中的任何一个,则会将它们从后端请求中删除,以表示未命中或命中未命中。
由于有条件的后端请求和304响应可能对不可缓存内容的性能至关重要,特别是在响应正文很大的情况下,我们再次提供了旧的一击即传功能, return(pass(DURATION))
在VCL。
与命中未命中一样,Varnish使用缓存来记录命中传递对象,并在随后的查找中再次找到它们。然后,将像处理普通通行证一样处理这些申请 (return(pass)
从… vcl_recv
)--没有请求合并,响应也不会被缓存,即使它本来可能是缓存的。 If-Modified-Since
或 If-None-Match
客户端请求中的头部在后端请求中被传递,并且具有状态304且没有正文的后端响应被传递回客户端。
对象的命中传球状态持续给定的时间,该时间是从 vcl_backend_response
。在“一击即传TTL”过去之后,下一个请求将是一个普通的未命中。因此,在经过该时间之前,命中传球对象不能再次变为可缓存对象。
304通过后未修改响应¶
与前一个主题相关的是,Varnish处理一个非常具体的案例的方式发生了变化:决定是否在通过后向客户端发送“304 Not Modify”响应,此时后端有机会发送304响应,但选择不发送200响应状态。
以前,当发生这种情况时,Varnish会与后端一起发送200响应和响应正文给客户端。即使后端设置了响应头,情况也是如此 ETag
和/或 Last-Modified
因此,当与请求标头相比时 If-None-Match
和 If-Modified-Since
,304的回应似乎是有必要的。由于这些标头被传递回客户端,因此从客户端的角度来看,结果可能看起来有点奇怪--客户端使用请求标头来询问响应是否未修改,而响应标头似乎表明它没有修改,但响应状态表明它是未修改的。
现在,只在交付时根据客户端请求头的内容和Varnish准备发送的响应中的头来决定是否发送304客户端响应状态,而不考虑后端获取是否是PASS。因此,Varnish可能会在传递后发送304客户端响应,即使后端在看到相同的请求头后选择不发送(如果响应头允许的话)。
为了保持一致性,我们进行了此更改--对于命中、未命中、命中未命中、命中换传球,以及现在的传球,是否发送304客户端响应的决定完全基于客户端请求头和响应头的内容。
您可以使用VCL方法恢复以前的行为--如果后端没有,则不要在PASS上发送304客户端响应--方法是删除 ETag
或 Last-Modified
页眉位置 vcl_backend_response
中的If-*客户端请求标头 vcl_pass
。
VSL查询中的VXID¶
从Varnish 4.0开始,Varnish共享日志(VSL)变得更加强大,此后没有太大变化。更改通常在于在引入新功能时添加新的日志记录,或者当我们意识到某些缺失的信息确实有助于故障排除时。
依赖于VSL的Varnish实用程序(VUT)通常共享相同的 -q
查询选项,允许根据日志记录过滤交易。例如,您可能正在查找特定域上的数字::
varnishtop -i ReqURL -q 'ReqHeader:Host eq www.example.com'
而选项,如 -i
和 -q
都仅限于日志记录,这也意味着您只能使用 X-Varnish
标题。根据事务的性质(客户端或后端),语法是不同的,您不能匹配会话。
例如,我们正在寻找最近发生的交易1234,我们希望从同一会话中收集所有信息。我们有两个选择:
# client side
varnishlog -d -g session -q 'RespHeader:X-Varnish[1] == 1234'
# backend side
varnishlog -d -g session -q 'BereqHeader:X-Varnish == 1234'
在引入之前,没有简单的方法可以使用任何事务的id来匹配它 vxid
作为可能的左侧 -q
查询表达式::
# client side
varnishlog -d -g session -q 'vxid == 1234'
# backend side
varnishlog -d -g session -q 'vxid == 1234'
# session
varnishlog -d -g session -q 'vxid == 1234'
另一个用例是收集非事务日志。使用RAW分组时,输出的组织方式不同,每条记录都以其事务ID开头,对于非事务日志,则以零开头:
# before 5.1
varnishlog -g raw | awk '$1 == 0'
# from now on
varnishlog -g raw -q 'vxid == 0'
这应该会为您提供一种更简洁、更一致的方式来过滤事务 varnishlog
还有其他的火鸡。
项目工具改进¶
我们在项目内部使用的工具上花费了相当多的时间。
这个 varnishtest
程序已在许多小方面进行了改进,尤其是现在使用 shell
和 process
命令。如果您已经在使用,它可能会破坏现有的测试用例 varnishtest
。
该项目现在有了 KISS Web后端,它总结了 make distcheck
来自不同平台的结果:
http://varnish-cache.org/vtest/
如果希望在尚未介绍的平台上测试Varnish,则只需从源代码树中运行Tools/vest.sh脚本即可。我们希望看到更多的平台被覆盖(ARM64、PPC、MIPS),OS/X也会很好。
我们现在还发布我们的代码覆盖状态:
http://varnish-cache.org/gcov/
我们的目标是90%以上的覆盖率,但我们需要开始在 varnishtest
在我们可以全面测试基于诅咒(1)的程序(top/stat/hist)之前,它们目前将我们拖下水。