【问题标题】:Varnish Cache not Caching PHP with Sessions Unless backend TTL altered清漆缓存不使用会话缓存 PHP 除非后端 TTL 更改
【发布时间】:2023-04-11 03:57:01
【问题描述】:

我是 Varnish Cache 的新手,有一个问题希望能得到一些帮助。

我有一个非常简单和基本的设置,但它没有按我的理解工作 应该是出于某种原因。

这与 Varnish 没有缓存使用 cookie 的 PHP 页面有关。

这是我的设置:

1) 对于我的 default.vcl,我有一个简单的后端

backend default {
.host = "127.0.0.1";
.port = "80";
}

2) 我有一个只有这两行的简单 PHP 文件:

session_start();
echo time();

3) 当我调用此页面时,它不会正确缓存 因为我没有添加所需的vcl规则

4)

所以根据我对我添加的文档的理解 在这两条规则中

sub vcl_recv {
unset req.http.Cookie;
return (lookup);
}

sub vcl_fetch {
unset beresp.http.Set-Cookie;
return(deliver);
}

5) PHP 页面仍然不会缓存。 我可以看到 Set-Cookie 标头已经 删除,因为我在 FireFox 中使用 FireBug。

只有当我将它添加到 sub vcl_fetch PHP 将缓存:

set beresp.ttl = 24h;

我的问题是这样对吗?

我认为我不需要更改 ttl 的后端响应。我以为只是不安 进出 cookie 会强制 PHP w/ session 缓存。

我完整的默认 vcl 是:

backend default {
.host = "127.0.0.1";
.port = "80";
}

sub vcl_recv {
unset req.http.Cookie;
return (lookup);
}

sub vcl_fetch {
unset beresp.http.Set-Cookie;
set beresp.ttl = 24h;
return(deliver);
}

我的启动命令是:

varnishd -f /etc/varnish/default.vcl -s malloc,128M -T 127.0.0.1:2000 -a 0.0.0.0:8080

我调用的网址是:

http://vbox.local:8080/varnish-tests/index.php

我的 index.php 文件只有:

<?php 
session_start();
echo time();

我想问问社区这看起来是否正确 或者如果我错了。基本上我只是不确定为什么我有 添加 beresp.ttl = 24h 以最终获得页面缓存 在清漆中。

我以为我不需要这个。

非常感谢任何建议。

谢谢!

亲切的问候。

【问题讨论】:

  • 这符合我的经验——我已经为我希望清漆缓存在我的 VCL 中的所有内容设置了 ttls。如果你不给它一个 ttl,你希望清漆缓存多长时间?
  • 嘿弗兰克。你的评论很有道理。我只是不确定,因为我没有注意到文档中关于设置与缓存 cookie 相关的 beresp.ttl 的任何内容。也许我在文档中忽略了这一点。我花了 30 多分钟挠头,直到我“想通”了。再次感谢。
  • 缓存处理会话的 PHP 响应时需要注意的事项:PHP 将默认 send anti-caching headers。如果 Varnish 遵循这些标头,那么如果您期望特定的缓存行为(一旦您解决了当前的问题,这完全不相关),您可能会遇到困难。

标签: php cookies varnish


【解决方案1】:

您应该非常仔细地查看 PHP 发送给 Varnish 的标头(例如,通过直接访问您的服务器而不是通过 varnishd)。如果标头说内容无法缓存,则不会。如果他们不说它可以被缓存,它就不会 - 我怀疑这就是为什么 Varnish 仅在您手动设置 ttl 时才缓存的原因,因为标头没有“过期”或“最大年龄” ”。

【讨论】:

    【解决方案2】:

    获取 varnish 缓存的响应的最简单方法是添加缓存控制标头。

    php:

    header('Cache-Control: public, s-maxage=60');
    

    会告诉 varnish 将响应缓存 60 秒。

    【讨论】:

      【解决方案3】:

      正如 ZoFreX 所说,这可能是因为您的 Cache-Control 或 Expires 标头。

      还要注意这条规则有点危险:

      sub vcl_recv {
          unset req.http.Cookie;
          return (lookup);
      }
      sub vcl_fetch {
          unset beresp.http.Set-Cookie;
          return(deliver);
      }
      

      如果您的服务器发送 cookie,那可能是因为您需要它们,至少对于会话而言。 这种规则将完全禁用您的应用程序服务器的会话管理。

      根据您使用会话的原因,您无法缓存内容的每一部分(例如:用户特定内容)。

      【讨论】:

        【解决方案4】:

        我遇到了完全相同的问题。当您执行 session_start 时,PHP 似乎注意到该页面可能是动态的,并有助于将缓存控制标头重置为:

        Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
        Pragma:no-cache
        

        Varnish 的默认配置遵循 apache/php 发送的这些缓存指令,这意味着它不会缓存这些页面。我也不是 100% 确定是否可以覆盖默认配置,只是为了扩展它。

        我一直在使用的解决方法是重新设置 Cache-Control 标头,但请注意,这必须在 session_start 更改它们之后完成。我还没有测试它是否也需要在 session_write_close 之后,但比抱歉更安全。

        【讨论】:

          【解决方案5】:

          Varnish 将遵循响应中的缓存标头。 PHP 将发送缓存控制标头而不是默认缓存响应

          Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
          Pragma:no-cache
          

          您需要禁用这些标头,否则 Varnish 将服从,因此不会缓存页面。要关闭它们,只需使用空字符串调用 session_cache_limiter()

          session_cache_limiter('');
          header("Cache-Control: public, s-maxage=60");
          session_start();
          

          然后您可以添加一个标头以将缓存控制设置为公共。使用上面的三行将启用缓存。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-07-21
            • 2012-04-03
            • 2011-07-02
            • 1970-01-01
            • 2013-01-09
            • 1970-01-01
            • 1970-01-01
            • 2018-07-18
            相关资源
            最近更新 更多