如何清除清漆中的完整缓存?

Posted

技术标签:

【中文标题】如何清除清漆中的完整缓存?【英文标题】:How to clear complete cache in Varnish? 【发布时间】:2016-12-17 22:28:35 【问题描述】:

我正在寻找一种方法来清除 Varnish 中所有域和所有 URL 的缓存。

目前,我需要为每个 URL 发出单独的命令,例如:

curl -X PURGE http://example.com/url1
curl -X PURGE http://example.com/url1
curl -X PURGE http://subdomain.example.com/
curl -X PURGE http://subdomain.example.com/url1
// etc.

虽然我正在寻找一种方法来做类似的事情

curl -X PURGE http://example.com/*

这样会清除 example.com 下的所有 URL,还会清除 example.com 子域中的所有 URL,基本上是 Varnish 管理的所有 URL。

知道如何实现吗?

这是我当前的 VCL 文件:

vcl 4.0;

backend default 
    .host = "127.0.0.1";
    .port = "8080";


sub vcl_recv 
    # Command to clear the cache
    # curl -X PURGE http://example.com
    if (req.method == "PURGE") 
        return (purge);
    

【问题讨论】:

您是否尝试使用禁令?这可能正是您想要的。 book.varnish-software.com/4.0/chapters/… 【参考方案1】:

假设 URL 或内部缓存键没有更改,对于完全刷新,最简单的方法是重新启动 Varnish,因为它会在内存中维护其缓存。

如果不能接受快速重启,Rastislav 建议的 BAN 是一个很好的方法。只要您最长的 TTL,它就需要保持活动状态,因此,如果您经常需要完全刷新,则 BAN 列表将几乎是永久的,因为禁令潜伏者(扫描不再相关的 BAN)可能总是认为您的 BAN很有用

所以在你的情况下,你的 VCL 将是:

# Highly recommend that you set up an ACL for IPs that are allowed
# to make the BAN call
acl acl_ban 
    "localhost";
    "1.2.3.4"/32;


sub vcl_recv 
   if (client.ip ~ acl_ban && req.method == "BAN") 
      ban("req.http.host == " + req.http.host);
      # Throw a synthetic page so the request won't go to the backend.
      return(synth(200, "Ban added"));
   

然而,正如 Carlos 在 cmets 中所指出的,这实际上会创建一个 lazy 失效(因此仅在请求时删除)。如果您想让这些对象每隔一段时间被background ban lurker 清除,您可以这样做:

# Highly recommend that you set up an ACL for IPs that are allowed
# to make the BAN call
acl acl_ban 
    "localhost";
    "1.2.3.4"/32;


sub vcl_recv 
   if (client.ip ~ acl_ban && req.method == "BAN") 
      # see below for why this is obj. rather than req.
      ban("obj.http.host == " + req.http.host);
      # Throw a synthetic page so the request won't go to the backend.
      return(synth(200, "Ban added"));
   


sub vcl_backend_response 
   # add any portions of the request that would want to be able
   # to BAN on. Doing it in vcl_backend_response means that it
   # will make it into the storage object
   set beresp.http.host = bereq.http.host;


sub vcl_deliver 
   # Unless you want the header to actually show in the response,
   # clear them here. So they will be part of the stored object
   # but otherwise invisible
   unset beresp.http.host;

然后进行冲洗:

curl -X BAN http://example.com;

【讨论】:

没错,但请注意,您在 vcl_recv 中创建的禁令对潜伏者不友好。禁令潜伏者将忽略它。在某些情况下这并不重要,但是如果您的禁令要匹配存储中的大量对象,您应该避免延迟失效并允许禁令潜伏者清除对象。创建对潜伏者友好的禁令需要更多的 VCL 行。详情请查看varnish-cache.org/docs/trunk/users-guide/purging.html#bans。 这是一个很棒的笔记!考虑到这一点,我会修改答案。 来自 VCC 编译器的消息:varnish-dev | “beresp.http.host”:不能在方法“vcl_deliver”中取消设置。清漆开发 |在: ('/etc/varnish/conf.d/varnish.vcl' Line 195 Pos 10) varnish-dev |取消设置 beresp.http.host;【参考方案2】:

使用 Varnish 4.0,我最终使用 ban 命令实现它:

sub vcl_recv 
    # ...

    # Command to clear complete cache for all URLs and all sub-domains
    # curl -X XCGFULLBAN http://example.com
    if (req.method == "XCGFULLBAN") 
        ban("req.http.host ~ .*");
        return (synth(200, "Full cache cleared"));
    

    # ...

【讨论】:

不需要写VCL来提交ban。无论如何,要走的路应该是创建一个对潜伏者友好的禁令。详情请见varnish-cache.org/docs/trunk/users-guide/purging.html#bans。 虽然这可行,但对于具有大量对象的缓存来说效率不是很高。我建议未来的读者在下面查看 Joshua DeWald 的答案,它对潜伏者友好,因此在 Varnish 上更容易处理。【参考方案3】:

好吧,我建议重新启动清漆。它将清除所有文件,因为 varnish 将缓存保存在内存中。

运行:sudo /etc/init.d/varnish restart

【讨论】:

这将导致服务器停机。我建议改为运行 varnishadm "ban req.url ~ /"【参考方案4】:

从命令行清除所有 Varnish 缓存(使所有缓存无效):

varnishadm "ban.url ."  # Matches all URLs

注意:Varnish 2.x 中的命令是 purge.url。

我们也可以通过主机名禁止:

varnishadm "ban req.http.host == xxx.com"

【讨论】:

之后如何解禁? 这似乎不可能以任何简单的方式.. #upvoteregrets 似乎在 varnish5 中他们稍微改变了命令。设法清除所有清漆缓存varnishadm 'ban req.url ~ .'

以上是关于如何清除清漆中的完整缓存?的主要内容,如果未能解决你的问题,请参考以下文章

什么是清漆中的管道模式和传递模式

如何设置清漆缓存控制头

使用 HTTP 和 REGEX 清除清漆

PHP 中的子资源完整性和缓存破坏技术

如何清除电子(原子壳)中的缓存数据?

wget --mirror 不创建清漆缓存