【问题标题】:Configuring Varnish 6 with grace mode, vcl_hit is never executed使用宽限模式配置 Varnish 6,永远不会执行 vcl_hit
【发布时间】:2018-09-02 03:24:58
【问题描述】:

我正在尝试将 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);
        }
    }
}

然后,当我收到日志消息时: tail -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

任何想法来获得预期的行为?

【问题讨论】:

    标签: varnish


    【解决方案1】:

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

    使用之前的配置,即使 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";
    }
    

    其他子程序配置相同。

    【讨论】:

      【解决方案2】:

      可能是来自后端的响应“不可缓存”。

      是否默认设置了任何Cache-Control 标头?还是饼干?

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

      unset beresp.http.Cache-Control

      如果您希望该标头在发送到客户端时为private, no-cache 以防止上游缓存,请在vcl_deliver 中重置它

      【讨论】:

      • 我尝试创建一个只返回时间的文件并设置标题: header('Cache-Control: public'); echo "此页面最后一次修改:".date("d.m.Y H:i:s",time());它只是第一次工作,缓存内容 1 分钟,但在那之后,我无法获取该文件的缓存。
      • 我尝试使用:“unset beresp.http.Cache-Control;”或“设置 beresp.http.Cache-Control = “max-age=3600”;”在 vcl_backend_response 中,但它不起作用。
      • 你的配置和我的唯一主要区别是我所有的时间都以秒为单位。你能试试beresp.grace = 3600s; 看看它是否有效吗?另一个技巧是将响应标头设置为调试记录器,以便您可以查看在什么条件下处理了请求:set req.http.X-Varnish-Cache = "hit";
      • 感谢您的帮助,我根据您的cmets解决了问题,并发布了解决方案。
      猜你喜欢
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2020-01-23
      • 2021-08-19
      • 2012-05-30
      • 2016-06-30
      相关资源
      最近更新 更多