后端服务器
varnish有“后端”和“源”的概念。后端服务器是为varnish提供加速内容的服务器。
我们的首要任务是告诉varnish它从哪里可以找到后端服务器。打开你最喜欢的文本编辑器,并打开相关的vcl文件。
在vcl文件的开头有一段像这样的片段:
# backend default {
# .host = "127.0.0.1";
# .port = "8080";
# }
我们将这一段的注释移除,修改为下面这样:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
这样一段配置在varnish中定义了一个后端,叫做default。当varnish需要从后端服务器获取内容时,它将会连接localhost(127.0.0.1)的80端口。
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发送到什么地方。让我们来看看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 ~ /mobile/) ..
。
后端和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”或者其他以“foo.com”结尾的任何其他主机名。在这个例子中,是故意这么写的,但是你可能想让他更严格一点,也许需要想这样做:
sub vcl_recv {
if (req.http.host == "foo.com" || req.http.host == "www.foo.com") {
set req.backend_hint = foo;
}
}
Directors
你也可以将几个后端服务器编组,这个组就叫做Directors。这可以提供性能和灵活性。
你可以定义一些后端服务器并将它们编成组。这就需要你加载VMOD,一个varnish的模块,然后在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();
}
这个调度器是循环调度器。这意味着这个Director将以轮询的算法来分发请求。还有一个分配请求的算法,是的,你猜对了,就是随机的方式。如果这还不够,那么你还可以写自己的调度器。(参考编写调度器)
但是如果其中一台服务器出问题了怎么办呢?varnish可以直接将所有的请求都转发到正常运行的服务器上面吗?当然可以。这时候健康检查就派上用场了。
健康检查
我们先给一个调度器设置两个后端和健康检查。先定义后端:
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将会每5秒检查一次每个后端的健康状况,超时设为1秒。每个轮询会发送一个GET请求。如果在5个检测中有至少3个是成功的,varnish就会认为后端是健康的,反之,后端就是有问题的了。
想了解更多关于Probes的内容请点击Probes。
现在我们定义调度器:
import directors;
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(server1);
vdir.add_backend(server2);
}
你使用这个vdir调度器作为处理请求的后端,就像你使用一个简单的后端那样。varnish将不会发送请求给那些不健康的主机。
如果后端服务器宕机了,varnish也可以返回旧的内容。查看Misbehaving servers获取更多关于这方面的信息。
请注意,varnish会保证健康的probe会运行所有加载的VCLs。varnish会将哪些看起来差不多的probe进行合并。所以如果你有很多载入的vcl,那么不要修改probe的配置。卸载VCL将禁用probes。更多信息请查看ref:reference-vcl-director。