varnish有"后端"或者"源"服务器的概念。backend server提供给varnish加速的内容。css
第一步设置是告诉varnish从哪儿找到backend server。使用你喜欢的编辑器打开varnishd引入的VCL文件。html
VCL文件的开头有一小段有点像这样:java
# 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能够定义多个后端,也能够将几个后端放在一个后端集群里面已达到负载均衡的目的。后端
某些状况下你可能须要让varnish缓存多个后端的内容。你可能想让varnish映射全部的url在单个后端上,或者是多个后端。这里有些参数能够知足这样的需求。api
如今咱们须要在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中:app
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; }
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。能够提升性能和弹性(增长一台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就是干这事的!
如今咱们给一个调度器设置两个后端和健康检测。先定义后端:
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.