使用Varnish配置多个站点

Tom*_*Tom 48 configuration caching varnish

我们有一台服务器需要通过清漆服务多个域,例如example1.com,example2.com和example3.com

我们当前的.vcl文件如下所示:

sub vcl_recv {
  set req.http.Host = "example1.com";    
  lookup;
}
Run Code Online (Sandbox Code Playgroud)

如何为正确的传入请求设置正确的req.http.Host?

Cri*_*mar 87

您可以通过以下方式支持多个前端域:

 backend example1 {
     .host = "backend.example1.com";
     .port = "8080";
 }
 backend example2 {
      .host = "backend.example2.com";
      .port = "8080";
 }
 sub vcl_recv {
    if (req.http.host == "example1.com") {
        #You will need the following line only if your backend has multiple virtual host names
        set req.http.host = "backend.example1.com";
        set req.backend = example1;
        return (lookup);
    }
    if (req.http.host == "example2.com") {
        #You will need the following line only if your backend has multiple virtual host names
        set req.http.host = "backend.example2.com";
        set req.backend = example2;
        return (lookup);
    }
 }
Run Code Online (Sandbox Code Playgroud)

  • 如果你有`return(lookup)`,帖子可能无法正常工作,因为Varnish会转换任何发送请求的帖子请求.删除此代码,它将工作. (6认同)

小智 25

我正在使用类似于Cristian的设置,但在if子句中我将req.http.host与正则表达式匹配:

#for www.example.com or example.com
if (req.http.host ~ "^(www\.)?example\.com$") {
        set req.backend = example_com;
        return (lookup);
}

#with any subdomain support
if (req.http.host ~ "^(.*\.)?example2\.com$") {
        set req.backend = example2_com;
        return (lookup);
}
Run Code Online (Sandbox Code Playgroud)

不要忘记适当地设置后端!

  • 我可能会补充说`return(lookup);`是不必要的 - varnish默认是这样做的 (4认同)
  • 恕我直言,你应该编辑这个答案并使其完整(即添加后端等). (4认同)
  • 此外,您可以使用物理IP而不是域名作为后端,例如`backend ipaddr1 {.host ="xxx.xxx.xxx.xxx";` (2认同)

hye*_*ena 8

无法添加评论所以我们走了

清漆4的轻微修改

#for www.example.com or example.com
if (req.http.host ~ "^(www\.)?example\.com$") {
        set req.backend_hint = example_com;
        return (lookup);
}

#with any subdomain support
if (req.http.host ~ "^(.*\.)?example2\.com$") {
        set req.backend_hint = example2_com;
        return (lookup);
}
Run Code Online (Sandbox Code Playgroud)

用backend_hint替换后端

  • `vcl_recv`现在必须返回`hash`而不是`lookup` (4认同)

小智 6

我想在 Cristian Vidmar 和 msurovcak 的帖子中添加更多细节

"(req.http.host == "example1.com") " 模式:

我们已经使用所描述的模式在每台服务器上托管数十到数百个站点。

您可以在整个配置(vcl_fetch/vcl_backend_response、vcl_hash 等)中使用特定于站点的自定义规则继续使用

if (req.http.host == "example1.com") {

任何需要的例子。

将其与模板引擎相结合,允许通过包含自己逻辑的单个文件管理客户特定的配置(所有文件都包装在其站点特定的 if 块中以隔离代码)。

然后使用以下命令将每个单独的站点块包含到 default.vcl 中:

include "/etc/varnish/www.example1.com.vcl";

完全拆分后端的可选增强功能:

如果您托管完全不同的网站,那么拆分后端(和拆分缓存)是一个不错的选择。

如果站点相似(相同的代码库/js/css/images),运行资源域可能会很有趣,例如。所有站点都使用的 resources.example.com。

然后,您可以跨多个站点的每个公共元素使用单个缓存(并且具有非常高的命中率),并且仍然在各个 www 站点上保持差异。

使用拆分后端的另一种选择:

另一种选择是通过容器拆分 Varnish 实例。然后每个人都成为自己独立的世界,单独管理(以及生死)。这可能是一个很好的安全选项,并且在现代基础设施上,多个进程的开销最小。

这样做的一些优点是您可以支持不同版本的 Varnish 和每个实例的不同 Varnish 启动参数。

这对于单独的日志记录非常有用,可以利用每个实例的不同 ESI 模式和单独的内存/调整配置设置。

我们在www.section.io 上这样做,它还使我们能够在不同的地理位置运行不同的容器或在不同的位置运行相同的容器,以尽可能接近地理上分散的用户群。