【问题标题】:Varnish + Wordpress + Nginx - Prevent no-store no-cache must-revalidate headersVarnish + Wordpress + Nginx - 防止 no-store no-cache must-revalidate headers
【发布时间】:2019-04-23 03:48:46
【问题描述】:

大约一周前,我们推出了一款网络应用,但遇到了严重的负载高峰,并且宕机了近 2 个小时。我不会点名提及这家公司,但我们依靠他们的建议来防止这种确切的事情发生。

他们说,由于我们使用 Varnish,我们可以很容易地处理流量涌入。但是,我们没有验证缓存是否按预期工作。不是。


TLDR:我们的网络应用正在发送带有请求的 Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 标头,但没有任何迹象表明这是为什么。

我在哪里可以防止这些标头被发送?

PHP:5.6 Nginx:1.4.6 清漆:1.1 WordPress:4.6.12 木材:1.2.4

与我们合作的 linux 管理员表示,他们仔细检查了配置,但除了 AJAX 请求外,没有找到任何指定这些标头的内容。

#dont cache ajax requests

if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~ "(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php)")

当我们在网站上强制使用 HTTPS(force-https 插件)后正确配置 Varnish 以进行缓存时,这是 Pre-launch 的一个 curl:

$ curl -Ik -H'X-Forwarded-Proto: *************
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Vary: Accept-Encoding
X-Server: *****
Date: Sat, 03 Nov 2018 22:36:43 GMT
X-Varnish: 53061104
Age: 0
Via: 1.1 varnish
Connection: keep-alive

从发布后开始:

curl -ILk ***********
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
X-Varnish: 691817320
Vary: Accept-Encoding
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type: text/html; charset=UTF-8
X-Server: ****
Date: Mon, 19 Nov 2018 19:17:02 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Accept-Ranges: bytes
Via: 1.1 varnish
Connection: Keep-Alive
Set-Cookie: X-Mapping-fjhppofk=33C486CB71216B67C5C5AB8F5E63769E; path=/
Age: 0

Force-https 插件:我们激活了这个插件,更新了 Varnish 配置以避免重定向循环,并在发布前一周确认它可以工作。

插件:这些没有改变,除了 force-https。

Web 应用程序:它是之前应用程序的更新版本,完全重新设计,但据我所知,应用程序中没有指定要发送的 no-store no-cache 标头。

我应该从哪里开始?谢谢!

【问题讨论】:

    标签: wordpress nginx varnish varnish-vcl timber


    【解决方案1】:

    您需要修复后端,但至少,您可以去除烦人的标头,和/或使用此 vcl sn-p 在清漆中绕过它;

    sub vcl_backend_response {
        # kill the CC header so that application downstream don't see it
        unset req.http.Cache-Control;
    
        # alternatively, you can also override that header with
        # set req.http.Cache-Control = "whatever string you desire";
    
        # you can also force the TTL
        beresp.ttl;
    
        # also, if you return now, the builtin.vcl (https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl)
        # doesn't get executed; this is generally the one deciding content is uncacheable
        return (deliver);
    }
    

    【讨论】:

      【解决方案2】:

      发送这些标头的是 PHP 引擎。

      每当您启动会话时都会这样做,这显然是基于Set-Cookie 的存在而发生的。

      确保仅在绝对需要时才启动 PHP 会话。默认情况下,当响应包含 Set-Cookie 或“否定”Cache-Control 时,Varnish 不会缓存,你有两个。

      因此摆脱无关的session_start() 和/或setcookie() 调用是这里的关键。

      您可以找到更多信息,了解何时可以预期发送 here 的反缓存标头。

      【讨论】:

      • 丹尼尔,非常感谢您对此的澄清。它一直让我发疯。这是session_start()session_set_cookie_params() setup.php 的唯一出现:gist.github.com/Mk-Etlinger/845dbe94462f4701964e75d123098597 我不认为这是无关紧要的,但也许它是罪魁祸首。
      • 如果在functions.php 或将在每个页面上执行的类似位置中使用它,它本身就能够完全杀死 Varnish 缓存。你可能想在你的整个项目目录中grep -R X-Mapping .,从你的示例 curl 输出中找到设置特定 cookie 的内容。
      • 谢谢丹尼尔! grepping X-Mapping 没有任何回报。当我在要点中注释掉上述代码时,标题被删除。不幸的是,我们需要在我们的应用程序中使用会话来管理整个站点的社交登录。为什么这是使用会话时的默认行为?如果您使用 cookie 或会话,是否有特定原因不应该缓存?
      • 这是我目前正在阅读的内容 =) blog.fortrabbit.com/mastering-http-caching
      • 如果在存在 cookie 的情况下允许缓存,这可能可能导致一个用户看到为其他用户指定的内容。当 cookie 由后端设置或由客户端发送时,Varnish 会默认绕过缓存。事情很大程度上取决于 cookie 的性质。例如,如果这是用于以不同语言显示您的网站的 cookie,您可以tell Varnish to cache in presence of cookies。但如果这是一个登录 cookie(PHP 会话),那么你应该让 Varnish 做默认设置。
      猜你喜欢
      • 2011-01-25
      • 2013-08-11
      • 2022-11-17
      • 2016-04-28
      • 2015-02-14
      • 2011-11-26
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      相关资源
      最近更新 更多