varnish - 在 Varnish 4 中错误获取后,在 "probe"标记服务器不健康之前交付过时的内容

标签 varnish varnish-vcl varnish-4

我使用 stale-if-error 来传递过时的内容,而服务器在查看 gracekeep 对象选项时被标记为不健康在vcl_hit中。

问题是:进入vcl子例程vcl_backend_error(新鲜请求错误)后是否可以传递缓存对象。实际上,我在 vcl_hit 处传递了缓存对象,但查看下图,我不知道如何访问该请求的缓存对象。

https://www.varnish-software.com/book/4.0/chapters/VCL_Basics.html

来源:https://www.varnish-software.com/book/4.0/chapters/VCL_Basics.html

最佳答案

使用内置 VCL 时(参见下面的代码):

# Built-in 'vcl_hit'.
sub vcl_hit {
    if (obj.ttl >= 0s) {
        return (deliver);
    }

    if (obj.ttl + obj.grace > 0s) {
        return (deliver);
    }

    return (fetch);
}
  • 如果 vcl_backend_errorreturn (deliver) 触发的后台/异步后端获取到达期间vcl_hit你不用担心。它只是一个更新停滞对象的后台线程。停滞的内容已经交付给客户。

  • 如果 vcl_backend_errorreturn (fetch) 触发的同步后端获取到达期间vcl_hit你也不必担心。错误将会传递给客户端,但你别无选择。停滞的对象在 Varnish 存储中不可用。

但是,如果您自定义了vcl_hit当后端健康时限制宽限(请参阅下面的 VCL 示例代码),a return (fetch) vcl_hit期间执行将作为同步后端请求进行处理。客户端将等待后端响应。如果后端请求达到vcl_backend_error并且错误将被传递到客户端。 Varnish 存储中存在一个已停止的对象(在此示例中已停止超过 60 秒),但不会使用它。

# Customised 'vcl_hit'.
sub vcl_hit {
    if (obj.ttl >= 0s) {
        return (deliver);
    }

    if (std.healthy(req.backend_hint)) {
        if (obj.ttl + 60s > 0s) {
            return (deliver);
        }
    } else {
        if (obj.ttl + obj.grace > 0s) {
            return (deliver);
        }
    }

    return (fetch);
}

如果您想在同步后端获取失败时传递停滞的对象,在这种情况下您需要一些额外的 VCL 逻辑。这个想法如下面的代码所示:

backend fail_be {
    .host = "127.0.0.1";
    .port = "9000";
    .probe = {
        .url = "/give-me-a-non-200-please";
        .interval = 24h;
        .timeout = 1s;
        .window = 1;
        .threshold = 1;
    }
}

sub vcl_recv {
    # Force the non-healthy backend in case of restart because of a previous
    # failed backend fetch. This will force serving stalled content using
    # full grace during 'vcl_hit' (if possible).
    if (req.restarts == 0) {
        unset req.http.X-Varnish-Restarted-5xx;
    } else {
        if (req.http.X-Varnish-Restarted-5xx) {
            set req.backend_hint = fail_be;
        }
    }

    # ...
}

sub vcl_synth {
    # 503 generated for synchronous client requests when abandoning the
    # backend request (see 'vcl_backend_fetch') and not executing a POST.
    if (resp.status == 503 &&
        req.method != "POST" &&
        !req.http.X-Varnish-Restarted-5xx) {
        set req.http.X-Varnish-Restarted-5xx = "1";
        return (restart);
    }

    # ...
}

sub vcl_backend_fetch {
    if (bereq.retries == 0) {
        unset bereq.http.X-Varnish-Backend-5xx;
    } else {
        if (bereq.http.X-Varnish-Backend-5xx) {
            # Jump to 'vcl_synth' with a 503 status code.
            return (abandon);
        }
    }

    # ...
}

sub vcl_backend_response {
    if (beresp.status >= 500 && beresp.status < 600) {
        set bereq.http.X-Varnish-Backend-5xx = "1";
        return (retry);
    }

    # ...
}

sub vcl_backend_error {
    set bereq.http.X-Varnish-Backend-5xx = "1";
    return (retry);
}

关于varnish - 在 Varnish 4 中错误获取后,在 "probe"标记服务器不健康之前交付过时的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32932632/

相关文章:

Varnish 版本显示为 "retired"

varnish - 制作 Varnish 日志time_firstbyte和处理

magento - wget --mirror 不创建 Varnish 缓存

Varnish VCL 检查 cookie 是否不存在

varnish - 在清除或禁止操作时,Varnish 4是否使用哈希键查找对象?

根据状态代码清空缓存项目

config - Varnish 4 日志记录代理/负载平衡器,而不是客户端 IP 地址

session-cookies - 如果启用 cookie,Symfony ESI 会破坏 Varnish 缓存

wordpress - 这个 vcl_hash 函数有什么作用?

cookies - 通过varnish设置cookie