【问题标题】:Following redirects internally with Varnish在内部使用 Varnish 进行重定向
【发布时间】:2016-07-17 01:19:25
【问题描述】:

我正在尝试使用 Varnish 4.1 实现 ruby​​gems 反向代理。我的 Intranet 中的客户端没有通用的出站 NAT,因此我需要 Varnish 在内部跟踪所有重定向,最好同时缓存来自 ruby​​gems.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。

【问题讨论】:

    标签: varnish varnish-vcl


    【解决方案1】:

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

    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

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-24
      相关资源
      最近更新 更多