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

问题描述 投票:0回答:2

我正在尝试将varnish 6.0.0配置为缓存服务器,当web服务器因维护而停机但我无法获得预期的行为。

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

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”永远不会被执行,因此当Web服务器出现故障时,立即从varnish中获取错误消息而不是来自varnish的缓存:

Error 503 Backend fetch failed
Backend fetch failed

Guru Meditation:
XID: 164960

Varnish cache server

有任何想法得到预期的行为?

varnish
2个回答
1
投票

我们使用的网页为用户提供了会话,因此我们需要确定用户何时登录。

使用先前的配置即使cookie为空,默认的清漆配置也不会为使用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";
}

其他子例程具有相同的配置。


0
投票

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

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

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

unset beresp.http.Cache-Control

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

© www.soinside.com 2019 - 2024. All rights reserved.