我的网站有一个有效的 Varnish 缓存,但有一个不良副作用,即对带有 http 的域名的请求会缓存在某个 URL 中,而对带有 https 的域名的请求会缓存在另一个 URL 中。这样,缓存中就会出现双重对象,我想问一些关于如何优化此行为的最佳实践。
具体来说,我在 nginx 中为同一个域设置了两个 vhost,分别监听端口 80 和 443。请求通过代理传递给 varnish:
proxy_pass http://varnish:8101/VirtualHostBase/http/example.com:80/path/VirtualHostRoot/;
和
proxy_pass http://varnish:8101/VirtualHostBase/https/example.com:443/path/VirtualHostRoot/;
在 varnish.vcl 中,我检查请求主机并设置正确的后端,因为有多个。
if (req.http.host == "example.com") {
set req.backend = backend_0;
}
后端是 Zope/Plone 服务器。页面在 varnish 中缓存正确,但我的 varnishlog (RxURL) 中有一个 /VirtualHostBase/http/example.com:80/path/VirtualHostRoot/logo.png 条目和一个 /VirtualHostBase/https/example.com:443/path/VirtualHostRoot/logo.png 条目。
当 Plone 清除条目时,只会清除 ssl 版本,因为每个登录用户都必须使用 https。http 条目将保留,直到年龄失效为止。
是否可以通过重写 URL 将 http 和 https 请求合并到一个 varnish 对象中?为了节省空间并成功清除。也许有人可以给我提示如何解决这个问题!
答案1
Varnish 通过 theirreq.url
和 their来识别不同的实体req.http.Host
(如果存在,则使用server.ip
)。你想要的是这样的:
sub vcl_hash {
#Example URL is:
# http://varnish:8101/VirtualHostBase/http/example.com:80/path/VirtualHostRoot/
#req.url contains only:
# /VirtualHostBase/http/example.com:80/path/VirtualHostRoot/
#after transform, this will become:
# /VirtualHostBase/fakescheme/example.com:fakeport/path/VirtualHostRoot/
hash_data(regsub(regsub(req.url,":(80|443)/",":fakeport/"),"/https?/","/fakescheme/")); #equivalent of "hash URL"
#Below here, copied from default.vcl
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (hash);
}
答案2
关于如何实现这一点的一个想法:
因此您需要设置:
- Varnish 反向代理
- 监听端口 *:80 并使用后端 localhost:8080
- Nginx 网络服务器
- 监听端口 *:443 并转发到 localhost:80
- 监听端口 localhost:8080 并提供网站服务
实际上,Nginx 已经可以配置为缓存反向代理。但是,如果您想要有特定的缓存规则,从缓存中清除单个对象等功能,Varnish 将是更好的解决方案。
暗示:
您必须检查您的网站是否能很好地使用相同的缓存对象来处理 http 和 https。如果网站使用绝对 URL 为外部内容(例如嵌入的媒体资产)提供 HTML、CSS 或 JavaScript,则无法正常工作。如您所知,浏览器不喜欢将 HTTP 资源嵌入 HTTPS 网站。