![Varnish‘client.ip’在方法‘vcl_backend_response’中不可用](https://linux22.com/image/762608/Varnish%E2%80%98client.ip%E2%80%99%E5%9C%A8%E6%96%B9%E6%B3%95%E2%80%98vcl_backend_response%E2%80%99%E4%B8%AD%E4%B8%8D%E5%8F%AF%E7%94%A8.png)
由于服务器升级,我们不得不从 Varnish 3 迁移到 Varnish 4。由于对服务器的了解很少,我能够更新新版本所需的设置和变量,但不幸的是,我遇到了瓶颈。
里面vcl_backend_response
我们需要使用client.ip
但不幸的是它不允许我们并且它会抛出这个错误:
Message from VCC-compiler:
'client.ip': Not available in method 'vcl_backend_response'.
At: ('input' Line 196 Pos 11)
if ( client.ip ~ traefik_acl && req.http.X-Forwarded-Host) {
----------#########----------------------------------------------
还有其他方法可以获取客户端 IP 吗vcl_backend_response
?
满的vcl_backend_response
sub vcl_backend_response {
if (beresp.http.content-type ~ "text" ||
beresp.http.content-type ~ "javascript") {
set beresp.do_gzip = true;
}
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120 s;
set beresp.uncacheable = true;
return (deliver);
}
if ( client.ip ~ traefik_acl && req.http.X-Forwarded-Host) {
set bereq.http.header.host = regsub(req.http.X-Forwarded-Host, ":.*$", "");
}
return (deliver);
}
答案1
Varnish v4.x 中的后端工作线程中该字段client
不可用。
解决方法是,你可以店铺客户端的 IP(或者在这种情况下可能只是他们通过了 ACL 检查的事实)作为req.http
新的标头,然后您可以通过子例程访问相同的标bereq.http
头vcl_backend_response
:
sub vcl_recv {
set req.http.foo = client.ip;
}
sub vcl_backend_response {
set beresp.http.Some-Header = bereq.http.foo;
}
在使用来自原始请求的信息时通常需要小心vcl_backend_response
,因为有可能为一个用户准备(并缓存)的响应最终会被另一个用户重新使用(从缓存中提供)。