Backend servers
varnish有"后端"或者"源"服务器的概念。backend server提供给varnish加速的内容。
第一步设置是告诉varnish从哪儿找到backend server。使用你喜欢的编辑器打开varnishd引入的VCL文件。
VCL文件的开头有一小段有点像这样:
# backend default { # .host = "127.0.0.1"; # .port = "8080"; # }
去掉注释后
backend default { .host = "127.0.0.1"; .port = "8080"; }
这样一段配置在varnish中定义了一个后端,被叫做default。(和c的函数定义有点相似),当varnish需要从后端获得内容时,它将连接127.0.0.1的8080端口。
varnish可以定义多个后端,也可以将几个后端放在一个后端集群里面已达到负载均衡的目的。
Multiple backends
某些情况下你可能需要让varnish缓存多个后端的内容。你可能想让varnish映射所有的url在单个后端上,或者是多个后端。这里有些参数可以满足这样的需求。
现在我们需要在PHP站点中引入java应用。java应用的链接都是以/java/开头的。 处理java应用的服务器监听在8000端口上。默认的default.vcl文件这样的:
backend default { .host = "127.0.0.1"; .port = "8080"; }
增加一个后端:
backend java { .host = "127.0.0.1"; .port = "8000"; }
现在需要告诉varnish将不同的url发送到不同的后端server。在vcl_recv中:
sub vcl_recv { if (req.url ~ "^/java/") { set req.backend_hint = java; } else { set req.backend_hint = default; } }
真的很简单。停下来思考下。正如你所看到的,你可以定义如何根据真实的任意数据来选择后端。你想发送手机设备的请求到不同的后端?没有问题。 可以满足你的需求。
if (req.http.User-Agent ~ "(?i)MIDP|WAP|UP.Browser|Smartphone|Obigo|Mobile|AU.Browser|wxd.Mms|WxdB.Browser|CLDC|UP.Link|KM.Browser|UCWEB|SEMC\-Browser|Mini|Symbian|Palm|Nokia|Panasonic|MOT|SonyEricsson|NEC|Alcatel|Ericsson|BENQ|BenQ|Amoisonic|Amoi|Capitel|PHILIPS|SAMSUNG|Lenovo|Mitsu|Motorola|SHARP|WAPPER|LG|EG900|CECT|Compal|kejian|Bird|BIRD|G900/V1.0|Arima|CTL|TDG|Daxian|DAXIAN|DBTEL|Eastcom|EASTCOM|PANTECH|Dopod|Haier|HAIER|KONKA|KEJIAN|LENOVO|Soutec|SOUTEC|SAGEM|SEC|SED|EMOL|INNO55|ZTE|iPhone|Android|Windows CE|Wget|Java|Opera") { set req.backend_hint = mobile; }
Backends and virtual hosts in Varnish
varnish完全支持虚拟主机。他们从来没有明确宣布这点是因为varnish以非常规的方式来实现这个功能。在vcl_recv我们设置处理HTTP请求的路由。如果你想让路由基于基本的虚拟主机做点什么,你只需要检查req.http.host便可。
sub vcl_recv { if (req.http.host ~ "foo.com") { set req.backend_hint = foo; } elsif (req.http.host ~ "bar.com") { set req.backend_hint = bar; } }
~符号后面的理解为正则表达式。这里可以匹配 "foo.com", "www.foo.com", "zoop.foo.com.cn" 还有其他包含foo.com的域名。该实例是有意写作如此,如果你明确了你的域名,你需要使用==来替代~符号。
sub vcl_recv { if (req.http.host == "foo.com" || req.http.host == "www.foo.com") { set req.backend_hint = foo; } }
Directors
你也可以将几个后端组成一组后端。这个组被叫做Directors。可以提高性能和弹性(增加一台app,或者停用一台app等等)。
你可以定义几个后端,然后将他们组织在一个Directors。这些操作需要你载入VMOD(varnish module),然后在vcl_init中调用这个VMOD。
import directors; # load the directors backend server1 { .host = "192.168.0.10"; } backend server2 { .host = "192.168.0.10"; } sub vcl_init { new bar = directors.round_robin(); bar.add_backend(server1); bar.add_backend(server2); } sub vcl_recv { # send all traffic to the bar director: set req.backend_hint = bar.backend(); }
该调度器是round-robin调度器。这意味着Directors将以轮询的算法来分发请求。还有一个random分配请求的director,你猜对了,随机的方式。
但是如果其中的某个server宕机了呢?varnish能将所有的请求分发到健康的server么?当然! Health Checks就是干这事的!
Health checks
现在我们给一个调度器设置两个后端和健康检测。先定义后端:
backend server1 { .host = "server1.example.com"; .probe = { .url = "/"; .timeout = 1s; .interval = 5s; .window = 5; .threshold = 3; } } backend server2 { .host = "server2.example.com"; .probe = { .url = "/"; .timeout = 1s; .interval = 5s; .window = 5; .threshold = 3; } }
.probe是新的参数。在上面的例子中varnish将每5s检测后端,超时设为1s。每个检测将会发送get /的请求。如果5个检测中大于3个是成功,varnish就认为后端是健康的,反之,后端就有问题了。
更多.probe的信息可以在varnish中查看Probes章节
我们现在定义director
import directors; sub vcl_init { new vdir = directors.round_robin(); vdir.add_backend(server1); vdir.add_backend(server2); }
你使用vir director作为处理请求的后端,就像你使用一个简单的后端那样。Varnish不会将请求发送到标记为不健康的后端上。
如果所有的后端都宕机了,varnish也可以返回给用户过期了的内容。查看Misbehaving servers获得更多如何开启这个功能的信息。
请注意,varnish将保持健康运行的探针对所有加载VCLs。Varnish将探针合并成似乎完全一体的-因此如果你有很多载入的VCL,不要修改probe的配置,卸载VCL将禁用probes。更多信息请查看ref:reference-vcl-director.