后端服务器

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。

results matching ""

    No results matching ""