以下重定向内部与清漆



我正在尝试使用 Varnish 4.1 实现 rubygems 反向代理。我的 Intranet 内的客户端没有通用的出站 NAT,因此我需要 Varnish 在内部跟踪所有重定向,最好缓存来自 rubygems.org 的 302 和来自 CDN 服务器的响应。

这是我的默认.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。

这不是一个明确的答案,但这里有一些想法:

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) 重试和重新启动是清漆 4 中的不同概念

这就是为什么bereq.retry总是显示0。您需要查看 req.restarts

最新更新