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

15

我正在寻找一种清除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);
    }
}

1
你尝试过使用“禁止(banning)”吗?这可能正是你想要的。http://book.varnish-software.com/4.0/chapters/Cache_Invalidation.html#banning - Rastislav Kassak
4个回答

17

我建议只需重启Varnish。这会清除所有文件,因为Varnish将缓存保存在内存中。

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


3
这将导致服务器停机。我建议运行 varnishadm "ban req.url ~ /"。 - TroodoN-Mike

17

我最终使用 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"));
    }

    # ...
}

1
不需要编写VCL来提交封禁。无论如何,应该创建一个友好的封禁监听器。有关详细信息,请参见https://varnish-cache.org/docs/trunk/users-guide/purging.html#bans。 - Carlos Abalde
虽然这个方法可以运行,但对于包含大量对象的缓存来说并不是很高效。我建议未来的读者查看下面Joshua DeWald的答案,它更加友好,因此对Varnish的处理更容易一些。 - Spikes

6
假设URL或内部缓存键不发生变化,对于完全刷新,最简单的方法是重新启动Varnish,因为它将其缓存保留在内存中。
如果不接受快速重启,则Rastislav建议的“BAN”是一个很好的方法。它需要保持活动状态,至少与您的最长TTL一样长,因此如果您经常需要完全刷新,那么BAN列表将几乎是永久性的,因为BAN lurker(清除不再相关的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"));
   }
}

然而,正如卡洛斯在评论中指出的那样,这实际上会创建一个“懒惰”的失效(因此只能在请求时删除)。如果您希望这些对象定期被背景禁令潜伏者清除,可以尝试以下操作:

# 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;

2
没错,但要注意你在“vcl_recv”中创建的禁止规则不适合lurker。它将被禁止lurker忽略。在某些情况下这并不重要,但如果你的禁止规则将匹配存储中的许多对象,则应避免懒惰失效并允许禁止lurker清除对象。创建适合lurker的禁止规则需要更多的VCL代码。请查看https://www.varnish-cache.org/docs/trunk/users-guide/purging.html#bans获取详细信息。 - Carlos Abalde
1
太好了,谢谢你的提醒!我会根据这个修改答案。 - Joshua DeWald
1
来自VCC编译器的信息: varnish-dev | 'beresp.http.host': 在方法'vcl_deliver'中无法取消设置。 varnish-dev | 在: ('/etc/varnish/conf.d/varnish.vcl' 第195行 第10个字符) varnish-dev | unset beresp.http.host; - benh57
@benh57 我怀疑我的答案在更新的Varnish版本中已经不再适用了 :/ - Joshua DeWald

5
从命令行清除所有Varnish缓存(使所有缓存无效):
varnishadm "ban.url ."  # Matches all URLs

注意:在Varnish 2.x中,命令为purge.url。
我们也可以通过主机名进行封禁:
varnishadm "ban req.http.host == xxx.com"

我该如何解禁它? - OZZIE
2
似乎没有任何简单的方法可以做到这一点。#后悔点赞 - OZZIE
1
似乎在Varnish5中,他们稍微更改了命令。使用varnishadm 'ban req.url ~ .'成功清除了所有Varnish缓存。 - Alex Berger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接