在内部使用Varnish重定向

时间:2016-07-15 19:33:29

标签: varnish varnish-vcl

我正在尝试使用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。

1 个答案:

答案 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