5. Varnish 和网站性能

本节重点介绍如何调整 Varnish 服务器的性能,以及如何使用 Varnish 调整网站性能。

本节分为三个小节。第一小节涉及您应该了解的 Varnish 的各种工具和功能。下一小节重点介绍如何清除缓存中的内容。清除内容在性能方面至关重要,因为它可以延长缓存对象的生存时间(TTL)。较长的 TTL 允许 Varnish 在缓存中保留更长时间的内容,这意味着 Varnish 会向相对较慢的后端发出较少的请求。

最后一个小节涉及网页内容的压缩。Varnish 可以在从后端获取内容时对其进行 gzip 压缩,然后将其压缩后交付。这将缩短下载内容的时间,从而提高网站性能。

5.1 实现高命中率

现在 Varnish 已经启动并运行,您可以通过 Varnish 访问您的网络应用程序。除非您的应用程序是专门为在网络加速器后面运行而编写的,否则您可能需要对配置或应用程序做一些更改,以便在 Varnish 中获得较高的命中率。

除非有绝对把握,否则 Varnish 不会缓存您的数据。因此,为了让您了解 Varnish 如何决定是否以及如何缓存页面,我们将指导您使用几个工具,您应该会发现这些工具对了解 Varnish 设置中发生的事情很有用。

请注意,你需要一个工具来查看在 Varnish 和后端之间传输的 HTTP 头信息。在 Varnish 服务器上,最简单的方法是使用 varnishlog 和 varnishtop,但有时也需要客户端工具。以下是我们常用的工具。

5.1.1 工具:varnishtop

varnishtop -i BereqURL 是一条必不可少的命令,可以显示 Varnish 发送到后台的最多请求。您可以在统计中查看 varnishtop 使用的其他一些示例。

5.1.2 工具:varnishlog

当您确定了经常发送到后端的 URL 后,您可以使用 varnishlog 查看该请求。varnishlog -q 'ReqURL ~ "^/foo/bar"' 将向您显示来自匹配 /foo/bar 的客户端的请求。

有关 varnishlog 如何工作的更多信息,请参阅 Varnish 中的日志记录 或手册页。

5.1.3 工具:lwp-request

lwp-request 是 Perl 的万维网库中的一个工具。它是几个非常基本的程序,可以执行 HTTP 请求并显示结果。我们主要使用 GET 和 HEAD 这两个程序。

vg.no是第一个使用Varnish的网站,那里运行Varnish的人都很有经验。因此,看看他们的 HTTP 头信息很有意思。让我们发送一个 GET 请求,访问他们的主页:

$ GET -H 'Host: www.vg.no' -Used http://vg.no/
GET http://vg.no/
Host: www.vg.no
User-Agent: lwp-request/5.834 libwww-perl/5.834

200 OK
Cache-Control: must-revalidate
Refresh: 600
Title: VG Nett - Forsiden - VG Nett
X-Age: 463
X-Cache: HIT
X-Rick-Would-Never: Let you down
X-VG-Jobb: http://www.finn.no/finn/job/fulltime/result?keyword=vg+multimedia Merk:HeaderNinja
X-VG-Korken: http://www.youtube.com/watch?v=Fcj8CnD5188
X-VG-WebCache: joanie
X-VG-WebServer: leon

好的。让我们看看 GET 的作用。GET 通常发送 HTTP 0.9 请求,缺少 "Host “头。因此,我们使用”-H "选项添加一个 "Host "头。-U “打印请求头,”-s “打印响应状态,”-e “打印响应头,”-d "丢弃实际内容。我们并不关心内容,只关心头信息。

正如你所看到的,VG 在头文件中添加了大量信息。其中一些标题,如 “X-Rick-Would-Never”,是 vg.no 及其古怪的幽默感所特有的。其他一些,如 “X-VG-Webcache”,则是用于调试目的。

因此,要检查网站是否为特定 URL 设置了 cookies,只需执行以下操作即可:

GET -Used http://example.com/ |grep ^Set-Cookie

5.1.3 工具:实时 HTTP 标头

Firefox 还有一个名为 Live HTTP Headers 的插件。该插件可以显示发送和接收的头信息。Live HTTP Headers 可在 https://addons.mozilla.org/en-US/firefox/addon/3829/ 或谷歌搜索 "Live HTTP Headers "找到。

5.2 HTTP标头的作用

伴随每个 HTTP 请求和响应而来的是一堆包含元数据的头信息。Varnish 会查看这些标头,以确定是否适合缓存内容,以及 Varnish 可以将内容缓存多长时间。

请注意,Varnish 在考虑这些标头时,实际上是将自己视为实际网络服务器的一部分。理由是两者都在您的控制之下。

IETF 或 RFC 2616 并没有很好地定义代理源缓存(surrogate origin cache)一词,因此 Varnish 的各种工作方式可能与您的期望不同。

让我们来看看您应该注意的重要标头:

5.2.1 Cookies

在默认配置下,Varnish 不会缓存来自后端的带有 "Set-Cookie "头的对象。此外,如果客户端发送 Cookie 头信息,Varnish 会绕过缓存直接访问后端。

这可能会过于保守。很多网站使用 Google Analytics (GA) 分析流量。GA 会设置一个 cookie 来跟踪您的访问。这个 cookie 由客户端的 javascript 使用,因此服务器并不关心。

来自客户端的 Cookie

对于许多网络应用程序来说,完全忽略 cookie 是有道理的,除非您访问的是网站的特殊部分。vcl_recv 中的这个 VCL 代码段将忽略 cookie,除非您正在访问 /admin/:

if (!(req.url ~ "^/admin/")) {
    unset req.http.Cookie;
}

非常简单。但是,如果您需要做一些更复杂的事情,比如从多个 Cookie 中删除一个,事情就变得困难了。不幸的是,Varnish 没有很好的工具来操作 Cookie。我们必须使用正则表达式来完成这项工作。如果你熟悉正则表达式,你就会明白这是怎么回事。如果您不熟悉,我们建议您阅读相关书籍、阅读 pcre2pattern man 页面或阅读许多在线指南。

这里我们以 Varnish Software (VS) 网络为例。VS 使用的设置非常简单,可以说是一个基于 Drupal 的后端和一个 Varnish 缓存。VS 使用一些用于 Google Analytics 跟踪和类似工具的 cookies。Cookie 全部由 Javascript 设置和使用。Varnish 和 Drupal 不需要看到这些 cookie,而且由于 Varnish 会在客户端发送 cookie 时停止页面缓存,因此 Varnish 会在 VCL 中丢弃这些不必要的 cookie。

在下面的 VCL 中,我们丢弃了所有以下划线开头的 cookies:

# Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

让我们来看一个例子,在这个例子中,我们删除了除名为 "COOKIE1 "和 "COOKIE2 "的 cookie 之外的所有内容,你会惊叹于它的 “美丽”:

sub vcl_recv {
    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(COOKIE1|COOKIE2)=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

        if (req.http.Cookie == "") {
            unset req.http.Cookie;
        }
    }
}

下面有一个更简单的例子,可以实现几乎相同的功能。它不是过滤掉 "其他 "cookie,而是挑选出所需的 "一个 "cookie,将其复制到另一个标头中,然后将其复制回请求中,删除原来的 cookie 标头。

sub vcl_recv {
    # save the original cookie header so we can mangle it
    set req.http.X-Varnish-PHP_SID = req.http.Cookie;
    # using a capturing sub pattern, extract the continuous string of
    # alphanumerics that immediately follows "PHPSESSID="
    set req.http.X-Varnish-PHP_SID =
       regsuball(req.http.X-Varnish-PHP_SID, ";? ?PHPSESSID=([a-zA-Z0-9]+)( |;| ;).*","\1");
    set req.http.Cookie = req.X-Varnish-PHP_SID;
    unset req.X-Varnish-PHP_SID;
}

Varnish Cache Wiki 中还有其他关于 VCL 可以完成的示例。

来自后端的 Cookie

如果您的后端服务器使用 "Set-Cookie "头设置了 cookie,则 Varnish 在使用默认配置时不会缓存页面。此时会创建一个 "命中-错过 "对象(参见 VCL 操作)。因此,如果后端服务器愚蠢地设置了不需要的 cookie,只需取消设置 "Set-Cookie "标头,一切都会好起来。

5.2.2 缓存控制

Cache-Control "头指示缓存如何处理内容。Varnish 会关注 max-age 参数,并用它来计算对象的 TTL。

因此,请确保您发出的 "Cache-Control "头带有 max-age 头。你可以看看 Varnish Software 的 Drupal 服务器都有哪些问题:

$ GET -Used http://www.varnish-software.com/|grep ^Cache-Control
Cache-Control: public, max-age=600

5.2.3 Age

Varnish 会添加一个 “Age”(年龄)标头,以显示对象在 Varnish 中保存了多长时间。您可以使用 varnishlog -I RespHeader:^Age__varnishlog __中找出 “Age”。

5.2.4 Pragma

HTTP 1.0 服务器可能会发送 Pragma: nocache 头信息。Varnish 会忽略这个头。您可以在 VCL 中轻松添加对该标头的支持。

在 vcl_backend_response:

if (beresp.http.Pragma ~ "nocache") {
    set beresp.uncacheable = true;
    set beresp.ttl = 120s; # how long not to cache this url.
}

5.2.5 授权

如果 Varnish 看到 "授权 "头,它就会通过请求。如果这不是您想要的,您可以取消设置该标头。

5.2.6 重写生存时间 (TTL)

有时,您的后端会出现问题。根据您的设置,在 Varnish 中重写 TTL 可能会比修复繁琐的后端更容易。

您需要 VCL 来识别您想要的对象,然后将 "beresp.ttl "设置为您想要的值:

sub vcl_backend_response {
    if (bereq.url ~ "^/legacy_broken_cms/") {
        set beresp.ttl = 5d;
    }
}

此示例将把网站上旧版内容的 TTL 设置为 5 天。

5.2.7 强制缓存某些请求和某些响应

由于您的后台可能仍然很繁琐,使用起来不是很方便,因此您可能希望在 Varnish 中覆盖更多内容。我们建议您尽量依赖默认的缓存规则。强制 Varnish 在缓存中查找对象非常简单,但并不推荐这样做。

5.2.8 标准化你的命名空间

有些网站通过很多主机名访问。。 http://www.varnish-software.com/http://varnish-software.com/http://varnishsoftware.com/ 都指向同一个网站。由于 Varnish 不知道它们是同一个主机名,因此 Varnish 会为每个主机名缓存不同版本的页面。您可以在网络服务器配置中通过设置重定向或使用以下 VCL 来解此问题:

if (req.http.host ~ "(?i)^(www.)?varnish-?software.com") {
    set req.http.host = "varnish-software.com";
}

5.3 HTTP Vary

*HTTP Vary 并不是一个简单的概念。它是迄今为止最容易被误解的 HTTP 标头。
*

很多响应头都会告诉客户端有关 HTTP 对象的一些信息。客户端可以根据自己的偏好,请求 HTTP 对象的不同变体。他们的偏好可能包括编码或语言等内容。当客户偏好英国英语时,可以通过 Accept-Language: en-uk 来表示。缓存需要将这些不同的变体区分开来,这可以通过 HTTP 响应标头 "Vary "来实现。
*

当后端服务器发出 Vary:当后端服务器发出 Vary: Accept-Language 时,它就会告诉 Varnish,它需要为来自客户端的每种不同的 Accept-Language 缓存一个单独的版本。
*

如果两个客户分别说他们接受 "en-us, en-uk "和 "da, de "这两种语言,如果后端表示 Varnish 需要在 “Accept-Language”(接受语言)标头上进行更改,那么 Varnish 将缓存并提供两个不同版本的页面。
*

请注意,"Vary "所指的标头必须完全匹配才行。因此,如果一个页面是为 "en-us, en-uk "创建的,而另一个页面是为 "en-us,en-uk "创建的,那么 Varnish 将保留该页面的两个副本。只要缺少空格,Varnish 就会强制缓存另一个版本。
*

因此,要在使用 Vary 的同时获得较高的点击率,关键是要将后端不同的头正常化。请记住,仅仅是不同的标题就会导致不同的缓存条目。
*

下面的 VCL 代码将把 "Accept-Language(接受语言)"标头规范化为 “en”、"de "或 “fr”,依次类推:*

if (req.http.Accept-Language) {
    if (req.http.Accept-Language ~ "en") {
        set req.http.Accept-Language = "en";
    } elsif (req.http.Accept-Language ~ "de") {
        set req.http.Accept-Language = "de";
    } elsif (req.http.Accept-Language ~ "fr") {
        set req.http.Accept-Language = "fr";
    } else {
        # unknown language. Remove the accept-language header and
        # use the backend default.
        unset req.http.Accept-Language
    }
}

5.3.1 改变解析错误

如果 Varnish 无法解析 "Vary "报头,或者 "Vary "报头中列出的任何客户端报头超过 65k 字符的限制,Varnish 将返回 "503 内部服务器错误 "页面。在这种情况下,系统会添加一个 "SLT_Error "日志条目。

5.3.2 Pitfall - Vary:用户代理

有些应用程序或应用服务器在发送内容时会同时发送 Vary:User-Agent。这会指示 Varnish 为每种不同的 "User-Agent "缓存一份单独的副本,而这些 "User-Agent "有很多。即使是同一浏览器的单个补丁级别,也会根据运行的操作系统生成至少 10 种不同的 "User-Agent "头。

因此,如果您真的需要根据 "User-Agent "进行更改,请务必将标头规范化,否则您的命中率将受到严重影响。以上述代码为模板。

5.4 缓存未命中

当 Varnish 在缓存中找不到请求的对象时,默认情况下它会从后端执行获取,假设响应可能被缓存。这有两个重要的后果:

  • 对同一对象的并发后端请求被合并- 一次仅执行一次提取,其他挂起的提取等待结果(除非您已实现下面不可缓存内容中描述的状态之一)。这是为了防止您的后端在缓存的响应过期或从未缓存过时受到“惊群”的攻击。如果结果表明第一次获取的响应已被缓存,则该缓存对象可以立即传递给其他待处理的请求。

  • 如果 Varnish 缓存中没有要验证的对象,则后端对缓存未命中的请求不能是有条件的;也就是说,它不能包含 headersIf-Modified-SinceIf-None-Match,这可能会导致后端返回状态“304 Not Modified”而没有响应正文。否则,缓存可能没有响应。如果这些标头存在于客户端请求中,则会从后端请求中删除它们。

通过设置缓存对象的宽限时间(默认为 10 秒),可以让 Varnish 在等待聚合获取(异步运行,同时将陈旧响应发送到客户端)时提供陈旧内容。详情请参阅 请参阅 Grace 模式和 keep

尽管条件请求的标头在缓存未命中时从后端获取中删除,但如果结果响应允许,Varnish 仍然可以用 “304 Not Modified” 响应客户端请求。在交付时,如果客户端请求的 标头与响应中的标头If-None-Match匹配,或者请求标头中的时间等于或晚于响应标头中的时间,则 Varnish 会将 304 响应发送给客户端。命中和未命中都会发生这种情况。

如果缓存中有可执行验证的对象,Varnish 可以向后端发送有条件请求。您可以在 vcl_backend_response中设置beresp.keep,确保为此目的保留对象:

sub vcl_backend_response {
  # Keep the response in cache for 4 hours if the response has
  # validating headers.
  if (beresp.http.ETag || beresp.http.Last-Modified) {
    set beresp.keep = 4h;
  }
}

过期对象的 TTL 和宽限时间过期后,beresp.keep 不会将其从缓存中删除。这将增加缓存的存储需求,但如果您有足够的空间,保留可验证很长时间的过期对象可能是值得的。如果后端能在 TTL 过期很长时间后发送 304 响应,就能节省获取带宽并减少对存储的压力;如果不能,那就与其他缓存缺失无异。

不过,如果您希望后端获取不带条件,只需删除vcl_backend_fetch 中的 If-* 标头即可。

sub vcl_backend_fetch {
  # To prevent conditional backend fetches.
  unset bereq.http.If-None-Match;
  unset bereq.http.If-Modified-Since;
}

仅当条件提取对后端有问题时才需要这样做,例如,如果评估响应是否未更改对于后端应用程序来说成本太高,或者响应只是有问题。从 Varnish 的角度来看,304 响应显然更可取;使用空响应主体进行提取可以节省带宽,并且不必在缓存中分配存储空间,因为现有的缓存对象被重新使用。

总而言之,即使在缓存未命中的情况下,您也可以通过以下方式提高性能:

  • 确保缓存的对象有一个宽限时间,在此期间可以向客户端提供陈旧的对象,同时在后台执行提取

  • 为缓存对象设置保留时间,在它们过时后可以通过 304 响应进行验证。

5.5 不可缓存的内容

由于各种原因,某些响应无法缓存。内容可能是个性化的,具体取决于标头的内容Cookie,或者可能只是根据每个请求重新生成的内容。缓存对此无能为力,但尽管如此,您可以做出一些决定,这将帮助 Varnish 以最适合您的要求的方式处理不可缓存的响应。

需要考虑的问题是:

  • 防止请求合并

  • 同一对象的响应是否(以及多久)可以再次被缓存

  • 是否要将客户端请求中的If-Modified-SinceIf-None-Matchheaders 传递到后端,以允许后端以状态 304 进行响应

5.5.1 传递客户端请求

根据网站的运行方式,您可能会识别出无法缓存响应的客户端请求,例如,如果 URL 符合某些模式,或由于请求头的内容。在这种情况下,可以使用 r vcl_recv 中的return(pass),将获取设置为传递:

sub vcl_recv {
  if (req.url ~ "^/this/is/personal/") {
    return(pass);
  }
}

对于传递,不存在请求聚合。由于 pass 指示响应不可缓存,因此等待可能被缓存的响应是没有意义的,并且对象的所有挂起的获取都是并发的。否则,等待最终无法缓存的对象的提取可能会被序列化 - 挂起的提取将等待第一个提取,当结果未进入缓存时,下一次提取开始,而所有其他提取都在等待,等等。

当请求被传递时,在vcl_backend_* 子程序中可以通过 bereq.uncacheableberesp.uncachable 均为 true 这一事实来识别。即使后端响应满足了允许缓存的条件,例如Cache-Control设置了正 TTL,也不会被缓存。

  • 请求方法是标准的 HTTP/1.1 方法,但不是GETHEAD

  • 有一个Cookie或 一个Authorization标头,表明响应可以是个性化的

如果你想覆盖默认值,例如,如果你确定尽管存在 Cookie,响应仍然是可缓存的,请确保在通过你自己的 vcl_recv 的任何路径的末尾调用 return。但是,如果这样做,内置 vcl_recv 的任何部分都不会被执行;因此,请仔细查看builtin.vcl中的 vcl_recv,并在自己的 vcl_recv 中复制需要的任何部分。

与缓存命中和未命中一样,如果客户端请求头和响应头允许,Varnish 会决定在通过后向客户端发送 304 响应。这可能意味着,即使后端看到了相同的请求头(If-Modified-Since和/或If-None-Match),但决定不以 304 状态响应,Varnish 仍会向客户端发送 304 响应,同时设置响应头 ETag 和 / 或 Last-Modified,使 304 看起来有正当理由。如果你不希望 Varnish 这么做,那就移除vcl_pass 中的 If-* 客户端请求头:

sub vcl_pass {
  # To prevent 304 client responses after a pass.
  unset req.http.If-None-Match;
  unset req.http.If-Modified-Since;
}

5.5.2 hit-for-miss

您可能无法在 vcl_recv 中识别所有不可缓存内容的请求。您可能希望允许后端通过设置 Cache-Control 头来确定自己的可缓存性,但这在 Varnish 收到后端响应之前是无法看到的,因此 vcl_recv无法知道。

默认情况下,如果请求未通过,且后端响应无法缓存,则通过在vcl_backend_response 中将 beresp.uncacheable设置为 true,将缓存对象设置为 “hit-for-miss”。缓存中会保存一个最小对象,以便在后续查询中识别 “hit-for-miss” 状态。(缓存用于在有限的时间内记住对象是不可缓存的)。在这种情况下,不会执行请求聚合,因此可以同时运行提取。否则,“hit-for-miss” 的获取就像缓存未命中一样,这意味着:

  • 响应可能会在以后的请求中变得可缓存,例如,如果它使用Cache-Control, 和设置正 TTL

  • 提取不能是有条件的,因此If-Modified-SinceIf-None-Match标头将从后端请求中删除。

beresp.uncacheable设置为 时true,则beresp.ttl 确定命中/未命中状态最多可以持续多长时间。hit-for-miss 状态在这段时间过去之后结束,或者如果在该时间过去之前后端返回了可缓存的响应(过去只是意味着beresp.ttl最小缓存对象过期,就像任何其他缓存对象过期一样)。如果返回可缓存的响应,则该对象将替换 hit-for-miss 的对象,并且对其的后续请求将是缓存命中。如果在过去之前没有返回可缓存响应beresp.ttl,则对该对象的下一个请求将是普通未命中,因此将受到请求聚合的影响。

当 Varnish 发现它在新请求上命中了 hit-for-miss 对象时,它会执行vcl_miss,因此您为缓存未命中编写的任何自定义 VCL 也将适用于 hit-for-miss 的情况。

builtin.vclberesp.uncacheable设置为 true,在许多指示响应无法缓存的条件下调用 hit-for-miss 状态,例如,如果 TTL 计算为 0 或存在标头Set-Cookieberesp.ttl在本例中设置为两分钟builtin.vcl,这就是默认情况下 hit-for-miss 持续的时间。

如果您需要在其他条件下 "hit-for-miss”,可以自行设置beresp.uncacheable

sub vcl_backend_response {
  if (beresp.http.X-This-Is == "personal") {
    set beresp.uncacheable = true;
  }
}

请注意,beresp.uncacheable设置为 true后就不能再设置为 false;在 VCL 中尝试这样做会被忽略。

虽然后端获取从来不会以 hit-for-miss 为条件,但如果客户端请求标头和响应标头或允许的话,Varnish 可能会决定(与所有其他情况一样)向客户端发送 304ETag 响应Last-Modified。如果想避免这种情况,请移除vcl_miss中的 If-* 客户端请求头:

sub vcl_miss {
  # To prevent 304 client responses on hit-for-miss.
  unset req.http.If-None-Match;
  unset req.http.If-Modified-Since;
}

5.5.3 hit-for-pass

“hit-for-pass” 的结果是后端获取不能是有条件的,因为“hit-for-pass”允许后续响应可缓存。对于非常大且不可缓存的响应,这可能会出现问题,但可以通过 304 响应进行验证。例如,您可能希望客户端每次都通过后端验证对象,仅在对象发生更改时才发送响应。

在这种情况下,可以使用 vcl_backend_responsereturn(pass(DURATION))将对象设置为“hit-for-pass”,其中 DURATION 决定了 hit-for-pass 状态持续的时间:

sub vcl_backend_response {
  # Set hit-for-pass for two minutes if TTL is 0 and response headers
  # allow for validation.
  if (beresp.ttl <= 0s && (beresp.http.ETag || beresp.http.Last-Modified)) {
    return(pass(120s));
  }
}

与 "hit-for-miss"一样,一个最小对象会被输入缓存,以便在后续请求中识别 "hit-for-pass "状态。然后,请求将作为通过处理,就像 vcl_recv 返回通过一样。这意味着不会出现请求聚合,客户端请求中的 If-Modified-SinceIf-None-Match 头信息会被传递到后端,因此后端的响应可能是 304。

Varnishvcl_pass在遇到 hit-for-pass 对象时执行。同样,您也可以在 VCL 中使用相同的代码自行处理 pass 和 hit-for-pass。

如果你想阻止 Varnish 向后端发送条件请求,那么就在 vcl_backend_fetch中删除后端请求中的 If-* 头信息,如上图所示,以防止缓存未命中。如果要防止 Varnish 在发送时根据客户端请求和响应头决定是否向客户端发送 304 响应,那么请在 vcl_pass 中删除客户端请求中的头,如上面的 pass 所示。

当返回语句中给出的 "hit-for-pass TTL "失效时,hit-for-pass 状态结束。与传递一样,对命中传递获取的响应永远不会被缓存,即使它会满足可缓存性的条件。因此,与“hit-for-miss”不同,不可能通过可缓存的响应提前结束“hit-for-pass”状态。在“hit-for-pass TTL”过去后,对该对象的下一个请求将被视为普通未命中。

req.hash_always_miss通过将命中对象的请求设置为true,可以结束缓存对象的“hit-for-pass”状态vcl_recv(您必须编写 VCL 来实现这一点)。发生这种情况的请求被强制为缓存未命中,并且对象随后的状态取决于后端响应的处置——它可能成为"hit"、“hit-for-miss"或再次被设置"hit-for-pass”。

"
hit-for-miss"是不可缓存内容的默认处理方式。没有任何部分builtin.vcl调用 hit-for-pass,因此如果您需要它,您必须将必要的return语句添加到您自己的 VCL 中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值