我正在尝试使用Varnish 4.1实现rubygems反向代理。我的Intranet中的客户端没有一般的出站NAT,因此我需要Varnish在内部跟踪所有重定向,最好从rubygems.org缓存302和CDN服务器的响应。
这是我的default.vcl:
vcl 4.0;
import std;
backend default {
.host = "rubygems.org";
.port = "80";
}
sub vcl_recv {
std.syslog(180, "doing vcl_recv");
std.syslog(180, "req.url = " + req.url);
}
sub vcl_deliver {
std.syslog(180, "doing vcl_deliver");
std.syslog(180, "resp.status = " + resp.status);
if (resp.status == 302) {
set req.url = resp.http.Location;
std.syslog(180, "restarting with req.url = " + req.url);
return(restart);
}
}
sub vcl_backend_fetch {
std.syslog(180, "doing vcl_backend_fetch");
std.syslog(180, "bereq.retries = " + bereq.retries);
}
sub vcl_backend_error {
std.syslog(180, "doing vcl_backend_error");
}
如果我curl -i http://localhost/latest_specs.4.8.gz
,Varnish会抛出HTTP 503并记录以下内容:
varnishd[20384]: doing vcl_recv
varnishd[20384]: req.url = /latest_specs.4.8.gz
varnishd[20384]: doing vcl_backend_fetch
varnishd[20384]: bereq.retries = 0
varnishd[20384]: doing vcl_deliver
varnishd[20384]: resp.status = 302
varnishd[20384]: restarting with req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_recv
varnishd[20384]: req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_backend_fetch
varnishd[20384]: bereq.retries = 0
varnishd[20384]: doing vcl_deliver
varnishd[20384]: resp.status = 302
varnishd[20384]: restarting with req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_recv
varnishd[20384]: req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_backend_fetch
varnishd[20384]: bereq.retries = 0
varnishd[20384]: doing vcl_deliver
varnishd[20384]: resp.status = 302
varnishd[20384]: restarting with req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_recv
varnishd[20384]: req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
varnishd[20384]: doing vcl_backend_fetch
varnishd[20384]: bereq.retries = 0
varnishd[20384]: doing vcl_deliver
varnishd[20384]: resp.status = 302
varnishd[20384]: restarting with req.url = http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
即使在更新req.url并重新启动请求后,它似乎也没有请求新的URL。
答案 0 :(得分:0)
这不是一个明确的答案,但这里有一些想法:
1)“req.url”仅包含URL的路径部分,但不包含URL的协议和主机部分。因此,当您在vcl_deliver中将“http://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz”分配给“req.url”然后重新启动时,我似乎完全没错。
在我看来,重启的请求不会出现“rubygems.global.ssl.fastly.net”,但仍然是“rubygems.org” - 定义的默认后端。
所以我猜你需要定义第二个后端“rubygems.global.ssl.fastly.net”并在重新启动时设置。你还需要做这样的事情(未经测试)
set resp.http.Location = regsub(resp.http.Location,"^http://","");
set req.http.host = regsub(resp.http.Location,"/.*$","");
set req.url = regsub(resp.http.Location,"[^/]*","");
2)重试和重启是varnish 4中的不同概念
这就是为什么bereq.retries总是显示0.你需要看看req.restarts