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

时间:2018-08-15 20:58:04

标签: varnish

当Web服务器因维护而停机时,我正在尝试将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

有得到预期行为的主意吗?

2 个答案:

答案 0 :(得分: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";
}

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

答案 1 :(得分:0)

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

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

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

unset beresp.http.Cache-Control

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