使用session_start()时,Varnish缓存无法缓存PHP页面

3

我第一次使用Varnish Cache,但是没有成功地让它按照我的意愿工作。

我的问题似乎很简单。

我想要缓存所有的 .php 页面。

到目前为止,每个 .php 请求都会经过 Varnish 缓存并且命中我的 Apache Web 服务器。

问题出在 cookies 和调用 session_start() 上。

没有 session_start() = 缓存生效 有 session_start() = 缓存失效

现在,文档很容易理解,但是我已经尝试了很多次,但都没有成功。只要我添加一个 session_start() 的调用,就再也没有缓存了。

这里是带有 PHP 的示例 HTML:

<?php 
session_start(); 
?>

<html>
<head>
</head>
<body>  

<?php echo date('Y-m-d H-i-s'); ?>

</body>
</html>

这是我的非常简洁干净的Varnish默认.vcl文件

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

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

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

这应该从客户端和服务器上取消Cookie,看起来确实如此。在使用此default.vcl进行调试时,使用FireFox中的FireBug可以看到Set-Cookie和Cookie HTTP标头不存在。

以下是FireFox的HTTP标头:

响应标头:

HTTP/1.1 200 OK
Server: Apache/2.2.16 (Debian)
X-Powered-By: PHP/5.3.3-7
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: text/html
Content-Length: 192
Date: Wed, 23 Feb 2011 01:34:17 GMT
X-Varnish: 2052563421
Age: 0
Via: 1.1 varnish
Connection: keep-alive

Request Headers:

GET /test.php HTTP/1.1
Host: xshare.com.local
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cache-Control: max-age=0

我就是看不出哪里出了问题。 我已经在.vcl配置文件中调整了2个小时,添加/修改和删除了代码行和变量。
有人能提供一些建议吗?
非常感谢。
2个回答

3
您可能已经发现,缓存和cookies不匹配。在上面的示例中,您将删除会话cookie(以及其他所有cookie),因此在使用Varnish时,您将无法使用会话。

有两件事情可以做: - 允许cookie但不为已登录用户获取缓存 - 除非确实需要,否则不要使用会话(或cookies)

第三个更复杂的解决方案是删除大多数页面的cookies,但允许它们用于某些页面,然后将它们处理为ESI块。有许多文档可供参考。


2

我已经找到了一组规则,现在可以缓存带有session_start()的.php页面。

我留下了其中一些我尝试过的规则但是被注释掉了。

通过反复试验,现在只需要两个配置规则。

一个用于客户端,一个用于服务器端。

Client = unset req.http.Cookie;

Server = set beresp.ttl = 5d;

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

sub vcl_recv {
  unset req.http.Cookie;
#  unset req.http.Cache-Control;
  return (lookup); 
}

sub vcl_fetch {
     if (beresp.http.Set-Cookie) {
         set beresp.ttl = 5d;
#         unset beresp.http.Set-Cookie;
#         unset beresp.http.Expires;
#         unset beresp.http.Cache-Control;
         return (deliver);
     }
}

欢呼。

如果您不从beresp中删除set-cookies,那么您将为所有用户缓存相同的cookies! - matheuzzy
会话的整个重点在于它对用户是唯一的 - 这就是为什么Varnish默认不缓存它们的原因。 - matpol

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