鉴于我们正在完成Varnish 3.0版本,大家可能认为很久前我就坚定地回答了这个问题,但是当你尝试变得高效时,事情也会变得棘手。
在基础层面,我们关注Varnish的一个功能是多VCLS同时加载的能力,并在他们之间能够及时快速切换。
你可以想想在VCL里面有1000台后端服务器,都是配置正确且含有健康检查配置的服务器。
现在你仅修改了一点点vcl_recv{},然后重新加载VCL,此时你也不确认哪种方式来解决这种情况,结果是保持了两种VCL加载,所以你可以在来回进行无缝切换。
为了达到无缝切换的目的,在我们切换到其他VCL的瞬间,每一个后端的健康状态需要处于最新。
这基本上意味着,要么全部VCL轮训所有的后端或者他们之间做到共享。
我们可以关闭所有VCL轮训所有后端的方案,因为这样确实很可怕,如果有人忘记在旧VCL里面使用vcl.discard,那么探测会持续进行。
除了健康状况外(包括saint列表), 我们也会共享打开的缓存连接数和统计数。
断开与后端的100个准备好的或可使用的连接,打开100个其他的,在一个拥有相同后端定义不同的VCL间做切换,这样做是不明智的。
在这种情况下什么样属于有相同的后端定义?
重要的是要明晰我们不是在讨论物理后端:举例说,拥有相同后端,却没有什么防护的VCL可以认为是4个不同后端。
最明显的事,可以通过使用VCL名字作为后端定义,但这还不够。我们可以有两套不同的VCL组成,当迁移或升级后端时,可以将”b”指向两个不同的物理机。
一旦健康状态在这些定义中存在,我们就需要在CLI中找到一种方式代表他们能做前后统计。
尽管我们可以把结果输出,虽然不是什么大不了的事,但是如果你想要1000台后端中一台的健康状况,你如何告诉我是那一台?
这样做的方式强制人们每次都输入:
backend.health b1(127.0.0.1:8080,[::1]:8080)
我确认那些只有一个后端的人不会命中。
我想即使我实现了我也不会承认,你可以这样书写通配符混杂方案:
b1 # 仅有一个b1后端或错误
b1() # 所有命名b1的后端
b1(127.0.0.1) # 所有基于IPv4本地检测的b1
b1(:8080) # 监听在8080的所有b1, (IPv4或IPv6)
b1(192.168.60.1,192.168.60.2) # 基于地址的所有b1
(受欢迎的输入)
最后一个问题,如果我们使用快捷符号输出Varnishd,答案是No。因为我们不想让计数器修改名字,当我们需要加载另一个VCL和突然要消除问题。
为了避免过度轮训,我们定义一个VCL同时对后端的最大轮训,并且灵活的VCL也受到偏爱。哪个特定的VCL轮训后端在灵活的VCL中是不重要的,只要他们之中一个可以实现就可以。
基于vcl.use的执行,对后端的轮训规范可以通过更新后端指针的轮训策略实现。
关于vcl.discard,如果这个vcl是有效状态的轮询器,那它需要遍历所有vcl列表,找到一个vcl进行替换;如果vcl列表是空的,那后端就会被移除。
我们或者在每个后端放一个线程,或者放一个轮训线程,当后端需要轮训时它能进到work池中扔掉在做的事。
匹配模式局限与在CLI和可能的libvarnishapi。
我想这可以工作,
下次再说,
Poul-Henning, 2010-08-09