1

我有一个在开发服务器上运行的清漆设置(Varnish 3),在生产服务器上运行相同的设置。除非我对其进行测试,否则开发服务器不会获得任何流量。生产服务器通过该 varnishinstance 获得了大约 80 个网站的大量流量。这些网站完全相同,因此所有网站都可以使用一个 VCL。

目前我正在使用 URL smart-bans 和 ban_lurker 进行测试。

我期望的是,当我添加禁令时,即使禁令由于某种原因不起作用,它也应该只在我的缓存 + 后端响应宽限期中最大的 TTL 保留在禁令列表中。

问题

问题是,在我的生产服务器上,禁令永远保留在禁令列表中(或者至少 24 小时,因为那是我给它的时间)。

所以我调整了我的 VCL,以便我希望任何缓存对象在缓存中停留的时间都不可能超过 20 分钟,因为我从我的 vcl_fetch 强制 20 分钟并将 beresp.grace 强制为 0。

在我的开发 varnishserver 上,这似乎完全一样。当我点击网站并以这种方式缓存一些东西时,然后将禁令放入,它在 20 分钟内就如预期的那样消失了。在我的生产服务器上,这似乎对禁令列表没有任何影响。它只是停留在那里。

我想念那里的东西吗?

VCL

有人可以看看我的 VCL 并告诉我我做错了什么吗?请注意,我遗漏了一些东西,例如后端配置和清除/禁止配置,因为我认为现在这并不重要。如我错了请纠正我 :)

import std;

# Define backends
include "backends.vcl";

# Define recv basics
sub vcl_recv {
    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE" &&
      req.request != "PURGE" &&
      req.request != "BAN") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
}

# Define purging and banning rules
include "purging-banning.vcl";

# Appart from PURGE and BAN requests, we only handle GET and HEAD requests
sub vcl_recv {
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }

    # Never cache monitor.php
    if (req.url ~ "^/monitor.php") {
         return (pass);
    }

    # in case of down backends serve content up to 30 minutes old
    if (req.backend.healthy) {
        set req.grace = 2m;
    } else {
        set req.grace = 30m;
    }
}

# Define purging and banning rules
include "recv-url-rules.vcl";

# If the URL's hasn't been caught by recv-url-rules.vcl, continue with common rules
sub vcl_recv {   
    # Don't cache AJAX requests
    if (req.http.X-Requested-With == "XMLHttpRequest") {
        return(pass);
    }
}

sub vcl_fetch {
    # Set default TTL of 20 minutes
    set beresp.ttl = 20m;

    # Keep objects in cache beyond their lifetime
    set beresp.grace = 0s; # for testing purposes

    # Don't cache if requested so by the server
    if (beresp.http.X-NoCache  == "no-cache" || beresp.http.cache-control ~ "private") {
        set beresp.ttl = 0s;
        set beresp.http.Cache-Control = "max-age = 0";
        return ( hit_for_pass );
    }

    # Pass (don't cache) big files (limit is just under 1MB)
    if ( beresp.http.Content-Length ~ "[0-9]{6,}" ) {
        set beresp.ttl = 0s;
        return ( hit_for_pass );
    }

    # Remember URL and HOST for the ban-lurker
    set beresp.http.x-url = req.url;
    set beresp.http.x-host = req.http.host;
}

sub vcl_deliver{
    # These were set for the ban-lurker, but don't have to be send to the client
    unset resp.http.x-url;
    unset resp.http.x-host;

    # Add a header to the request so that we can see wether or not the object came from cache
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

sub vcl_pipe {
    # http://www.varnish-cache.org/ticket/451
    # This forces every pipe request to be the first one.
    set bereq.http.connection = "close";
}

清漆文档

Varnish 文档说明如下:

在 Varnish 运行 vcl_fetch 之前,已经将 beresp.ttl 变量设置为一个值。>它将使用它找到的第一个值:

Cache-Control 响应标头中的 s-maxage 变量 Cache-Control 响应标头中的 max-age 变量 Expires 响应标头 default_ttl 参数。

那么在某些情况下,后端响应是否仍会覆盖 TTL?即使我在 vcl_fetch 中强制它?

4

1 回答 1

4

禁令将保留在禁令列表中,直到缓存中比它更早的所有对象都被检查过。如果您提供具有长 TTL 的长尾内容,则禁止列表会变得很长。

但是,由于每个对象只评估一次禁令,因此实际上没有任何缺点(除了美学)。别担心。

于 2014-05-02T13:58:19.803 回答