Varnish 5.0中的更改

Varnish 5.0更改了一些(主要是)内部API,并在Varnish 4.1的基础上增加了一些主要的新功能。

单独的VCL文件和VCL标签

Varnish 5.0支持从活动的VCL跳转 vcl_recv{} 通过VCL标签发送到另一个VCL。

它的主要用途可能是为每个域/vhost拥有单独的VCL,以便解开复杂的VCL文件,但它不仅限于此标准,还可以将来自特定IP范围的所有帖子、所有JPEG图像或所有流量发送到单独的VCL文件。

VCL标签还可以用来为加载的VCL配置赋予象征性名称,这样运营人员只需要知道“正常”、“周末”和“紧急”,网络开发人员就可以像往常一样更新这些,而不必告诉运营人员新的周末VCL叫什么。

非常实验性的HTTP/2支持

我们正在向Varnish添加HTTP/2支持,但代码非常环保--发生了。

但实际上你已经可以通过它获得一些流量,我们希望为下一个主要版本(2017-03-15)做好生产准备。

Varnish支持HTTP/1->2升级。出于政治原因,没有浏览器支持这一点,但像cURL这样的工具支持。

对于加密的HTTP/2流量,请在Varnish前面放置一个SSL代理。

默认情况下禁用HTTP/2支持,若要启用,请设置 http2 功能位。

《碎片导演》

我们在控制器VMOD中添加了一个经过改进的控制器版本,它作为树外VMOD以VSLP的名称提供了几年:它基本上是一个更好的散列控制器,当后端的配置和/或健康状态发生变化时,它使用一致的散列来提高后端节点选择的稳定性。有几个选项可以提供分片密钥。Rampup功能允许将刚刚正常的后端平稳地投入生产,而预热功能允许为流量准备后端,如果某个密钥的主后端出现故障,他们将看到这些后端。

它可以动态重新配置(在外部 vcl_init{} ),但与我们的其他控制器不同,配置是事务性的:任何一系列后端更改都必须通过调用重新配置以激活来结束。

击球传球现在实际上是命中失误

几乎从一开始(2008年)起,Varnish就命中即传:它基本上是一种负缓存特性,将对象作为标记放入缓存对象中,表示“当您命中此对象时,您的请求应该是传递的”。其目的是有选择地避免请求合并(等待列表)功能,该功能对可缓存的内容很有用,但对不可缓存的对象无效。如果我们没有命中即传,在vclrecv中没有额外的配置,对不可缓存内容的请求将被串行化发送到后端(一个接一个)。

尽管这个特性很有用,但它已经给管理员带来了许多令人头疼的问题,比如,为什么 beep Do‘t Varnish Cacheat This“:无论ttl规定的命中时间有多长,命中传递对象都会在缓存中停留很长时间,并在每次命中时阻止缓存(大多数情况下是针对该url)。尤其是,作为传递对象不能回溯转换为可缓存的对象 (beresp.uncacheable 可以从 falsetrue ,但不是反过来),即使是本来可以缓存的响应也没有缓存。因此,当一击即传对象无意中进入缓存时,它必须被显式删除(使用禁止或清除)。

我们现在已经改变了这一点:

命中传递对象(我们在文档、日志和统计中仍然这样称呼它)现在会导致所有后续请求的缓存未命中,所以如果任何后端响应符合缓存条件,它将被缓存,后续请求将被命中。

简而言之:我们已经从“不可缓存的案例赢了”变成了“可缓存的案例赢了”,或者从“传球命中”变成了“命中失误”。

在此版本发布时,我们意识到的主要后果是,为了创建可缓存对象,我们需要使后端请求无条件(即,删除 If-Modified-SinceIf-None-Match headers ):对于对命中传递对象的有条件的客户端请求,Varnish现在将发出无条件的后端获取,并且对于200个响应,根据需要向客户端发送304或200响应。

到本版本发布时,我们还不能说这是否会成为这个话题的最终定论,但我们希望这将意味着对大多数Varnish用户的改进。

禁止潜伏者改进

我们通过使用低效正则表达式的数以万计的禁令的真实情况的例子,使禁令潜伏者变得更加有效。

新参数 ban_lurker_holdoff 告诉禁令潜伏者,当它可能由于锁定争用而减慢查找速度时,它应该让开多长时间。在此之前,这与 ban_lurker_sleep

始终发送请求正文/“可缓存的帖子”

以前,我们只会为已传递的请求发送请求正文(对于管道模式,但这无论如何都是特殊的,应该避免)。

现在不再是这样了,但默认行为没有改变:

只要请求有正文,它就会因为缓存未命中而被发送到后端(并像以前一样传递)。这可以通过使用 unset bereq.body 以及 builtin.vcl 删除GET请求的正文,因为带正文的GET是否有效值得怀疑(但有些应用程序使用它)。

因此,经常请求的缓存POST/PATCH/的能力...现在可用,但不是开箱即用的:

  • 这个 builtin.vcl 仍然包含一个 return(pass) 除了GET或HEAD之外的任何东西,因为根据定义,其他HTTP方法可能会对后端造成状态更改/副作用。在考虑缓存非GET/非头之前,应该很好地理解手头的应用程序。

  • 对于未命中,核心代码仍会调用 set bereq.method = "GET" 在呼叫之前 vcl_backend_fetch ,所以要用原来的请求方法进行后端请求,需要保存在 vcl_recv 并在 vcl_backend_fetch

  • 应注意选择适当的缓存键和/或变化标准。使用核心Varnish不能将请求正文添加到缓存键,而是通过vmod https://github.com/aondio/libvmod-bodyaccess

总而言之:当缓存除GET或HEAD以外的任何内容时,您应该知道自己在做什么,如果不创建适当的缓存键,这样做几乎肯定是错误的。

ESI和后端请求合并(“waitinglist”)改进

以前,ESI子请求取决于从支持的对象获取的对象,使用轮询,这通常会给这些子请求增加大约5ms的处理时间,并且在极端的角落情况下可能会导致饥饿效应。

当等待的对象变为可用时,ESI子请求的等待列表逻辑现在使用条件变量触发ESI处理的立即继续。

后端代理协议请求

现在通过 .proxy_header 后端定义的属性。

默认VCL搜索路径

对于默认构建,现在还可以在以下位置查找vCL文件 /usr/share/varnish/vcl 如果未在以下位置找到 /etc/varnish

对于定制构建,实际的搜索路径为 ${varnishconfdir}:${datarootdir}/varnish/vcl

devicedetect.vcl

基本设备检测VCL现在与Varnish捆绑在一起。

Varnish测试

  • resp.msg 已重命名为 resp.reason 与VCL保持一致

  • 添加HTTP2测试功能

  • 添加的可执行文件和vmod的默认搜索路径

  • sema mechanism replaced by barrier

  • 支持代理请求

杂项

关于其他更改的简要说明

  • 为对象到期添加了单独的线程

  • ESI解析器现在可以更好地容忍某些语法转折点

  • 减少等待名单上不必要的请求匆忙

  • varnishhist 现在可以处理后端请求,并提供时间折弯功能来控制处理速度

  • std.integer() 现在还可以解析实数并截断它们

  • std.log() now also works correctly during vcl_init{}

  • 进一步提高了处理工作空间溢出时的稳定性

  • 大量的VCL编译器改进

VMOD作者新闻

  • 现在,必须在 $Module 一条线 vcc 文件。

  • vcl cli events (in particular, vcl_init{} /vcl_fini{}) now have a workspace and PRIV_TASK available for VMODs.

  • PRIV_* 现在也适用于作用域不变的对象方法。特别是,它们是按VMOD和 not 每个对象-例如相同 PRIV_TASK 在VCL任务期间作为函数传递给对象方法。

  • Varnish现在提供随机数API,请参见vrnd.h

  • 改进了VBM(可变大小位图)

  • vmodtool.py 由于翻译VCC文件已在很大程度上被重写,可能仍然存在未被注意到的回归

  • vmodtool.py 现在至少需要Python2.6

  • 新的Autoconf宏可用,它们应该会极大地简化树外VMOD的构建系统。它们在以下文件中实施和记录 varnish.m4 ,以前的宏现在位于 varnish-legacy.m4 因此,现有的VMOD应该仍然可以很好地构建。