使用 Varnish 配置多个站点
Posted
技术标签:
【中文标题】使用 Varnish 配置多个站点【英文标题】:Configure multiple sites with Varnish 【发布时间】:2011-03-21 00:38:45 【问题描述】:我们有一台服务器需要通过清漆服务多个域,例如example1.com、example2.com 和 example3.com
我们当前的 .vcl 文件如下所示:
sub vcl_recv
set req.http.Host = "example1.com";
lookup;
如何为正确的传入请求设置正确的 req.http.Host?
【问题讨论】:
【参考方案1】:无法添加评论,我们开始吧
对清漆 4 稍作修改
#for www.example.com or example.com
if (req.http.host ~ "^(www\.)?example\.com$")
set req.backend_hint = example_com;
return (hash);
#with any subdomain support
if (req.http.host ~ "^(.*\.)?example2\.com$")
set req.backend_hint = example2_com;
return (hash);
替换 后端 和 后端提示
【讨论】:
vcl_recv
现在必须返回 hash
而不是 lookup
【参考方案2】:
我想为 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/图像),运行资源域可能会很有趣,例如。所有网站都使用的 resources.example.com。
然后,您可以在多个网站的每个公共元素上拥有一个缓存(并且命中率非常高),并且仍然在各个 www 网站上保持差异。
使用拆分后端的另一种替代方法:
另一种选择是通过容器拆分 Varnish 实例。然后每一个都成为它自己的孤立世界,单独管理(生死)。这可能是一个很好的安全选择,并且在现代基础架构上,多个进程的开销最小。
这样做的一些优点是您可以支持不同版本的 Varnish 以及每个实例的不同 Varnish 启动参数。
这对于单独的日志记录非常有用,可以利用每个实例的不同 ESI 模式和单独的内存/调整配置设置。
我们在www.section.io 这样做,它还使我们能够在不同的地理位置运行不同的容器或在不同的位置运行相同的容器,以尽可能接近地理上分散的用户群。
【讨论】:
【参考方案3】:我正在使用类似于 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);
别忘了适当地设置后端!
【讨论】:
我可能会补充一点,return (lookup);
是不必要的——varnish 默认会这样做
另外,后端可以使用物理ip代替域名,如backend ipaddr1 .host = "xxx.xxx.xxx.xxx";
恕我直言,您应该编辑此答案并使其完整(即也添加后端等)。
很棒的回复,不应该使用查找,因为在复杂的配置中,子 vcl_recv 中还有很多其他的东西
对于 Varnish 4 lookup
已替换为 hash
。你现在应该改用return(hash);
。【参考方案4】:
您可以通过这种方式支持多个前端域:
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);
【讨论】:
这也匹配 www.backend1.com 和 backend1.com 吗? 如果您有return (lookup)
,帖子可能无法正常工作,因为 Varnish 会隐藏任何帖子请求以获取请求。删除此代码,它将起作用。
这太棒了。结合了你的答案和 msurovcak 的答案,但这非常有帮助。不错的一个
如果您正在监听非标准端口(可能在测试时),端口号必须包含在测试中。 if (req.http.host == "example.com:8080")
在 Varnish 4 中,req.backend
是 renamed 到 req.backend_hint
。以上是关于使用 Varnish 配置多个站点的主要内容,如果未能解决你的问题,请参考以下文章