使用宽限模式配置 Varnish 6,永远不会执行 vcl_hit

Configuring Varnish 6 with grace mode, vcl_hit is never executed

我正在尝试将 Varnish 6.0.0 配置为缓存服务器,当网络服务器因维护而关闭时,但我无法获得预期的行为。

我有下一个配置(使用宽限模式):

vcl 4.0;

import directors;
import std;

backend default {
    .host = "some.server.com";
    .port = "80";
    .probe = {
        .url = "/health_check.php";
        .interval = 5s;
        .timeout = 1s;
        .window = 5;
        .threshold = 3;
    }
}

sub vcl_recv {
    std.syslog(180, "RECV: recv");

    #Cache - grace mode
    set req.http.grace = "none";
}

sub vcl_backend_response {
    std.syslog(180, "RECV: backend");

    #Cache - grace mode
    set beresp.ttl = 10s;
    set beresp.grace = 1h;
    #set beresp.keep = 24h;
}

sub vcl_deliver {
    std.syslog(180, "RECV: deliver");

    #Cache
    set resp.http.grace = req.http.grace;
}

sub vcl_hit {
    std.syslog(180, "RECV: hit************************");

    if (obj.ttl >= 0s) {
        # normal hit
        return (deliver);
    }
    # We have no fresh fish. Lets look at the stale ones.
    if (std.healthy(req.backend_hint)) {
        # Backend is healthy. Limit age to 10s.
        if (obj.ttl + 10s > 0s) {
            set req.http.grace = "normal(limited)";
            return (deliver);
        } else {
            # No candidate for grace. Fetch a fresh object.
            return(miss);
        }
    } else {
        # backend is sick - use full grace
        if (obj.ttl + obj.grace > 0s) {
            set req.http.grace = "full";
            return (deliver);
        } else {
            # no graced object.
            return (miss);
        }
    }
}

然后,当我收到日志消息时: 尾巴-f /var/log/messages

我刚知道接下来的步骤:

varnishd[11801]: RECV: recv
varnishd[11801]: RECV: hash
varnishd[11801]: RECV: backend
varnishd[11801]: RECV: deliver

为此我知道子例程 "vcl_hit" 永远不会执行,所以当网络服务器关闭时,我立即从清漆而不是清漆缓存中收到错误消息:

Error 503 Backend fetch failed
Backend fetch failed

Guru Meditation:
XID: 164960

Varnish cache server

知道如何获得预期的行为吗?

可能是后台的响应是"uncacheable"。

它有没有默认设置 Cache-Control header?还是饼干?

您可以取消设置 header 或将其设置为允许缓存的另一个值:

unset beresp.http.Cache-Control

如果您希望 header 在发送到客户端时成为 private, no-cache 以防止上游缓存,请在 vcl_deliver

中重置它

我们使用的网页有一个用户会话,所以我们需要识别用户何时登录。

使用之前的配置,即使 cookie 为空,默认的 varnish 配置也不会为带有 cookie 的请求创建缓存。

所以我添加了一些行来使内容可缓存(在代码中解释):

sub vcl_recv {
    # intial state
    set req.http.grace = "none";

    # If our backend is down, unset all cookies and serve pages from cache.
    if (!std.healthy(req.backend_hint)) {
        unset req.http.Cookie;
    }

    # Are there cookies left with only spaces or that are empty?
    if (req.http.cookie ~ "^\s*$") {
      unset req.http.cookie;
    }

    # NO cache si NO es get o head --> ejm, post, read, delete, etc
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    # If server is healthy && user is in session --> no cache
    if (std.healthy(req.backend_hint)) {
        if (req.http.Authorization || req.http.cookie ~ "some_cookie=") {
            /* Not cacheable by default */
            return (pass);
        }
    }

    return(hash);
}

sub vcl_backend_response {
    #Cache - grace mode
    set beresp.ttl = 10s;
    #set beresp.ttl = 1h;
    set beresp.grace = 1h;
    set beresp.keep = 24h;

    set beresp.http.Cache-Control = "max-age=3600";
}

其他子程序配置相同