PHP会话导致varnish不缓存

时间:2015-07-24 16:09:03

标签: php session varnish

我正在努力理解清漆的行为,并希望有人可以解决这些问题。

我正在做一个测试,我正在尝试使用varnish来缓存请求/响应cookie。

我有一个非常简单的PHP脚本,它只需启动一个会话。

<?php session_start(); ?>

我确实希望清漆不会因 Set-Cookie Cookie 标头而缓存。

我会去取消这些标题:

sub vcl_backend_response {
    unset beresp.http.set-cookie;
}

sub vcl_recv {
    unset req.http.cookie;
}

请求的页面仍然未被缓存

我知道PHP会发送一个可能受varnish尊重的缓存破坏标头。我们来看看:

<?php echo session_cache_limiter(); ?>

输出: nocache

session_cache_limiter()文档中可以看出 nocache 会发送这些响应标头以破坏缓存:

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

让我们取消它们:

sub vcl_backend_response {
    unset beresp.http.expires;
    unset beresp.http.pragma;
    unset beresp.http.cache-control;
    unset beresp.http.set-cookie;
}

至于这一点,我希望varnish能够缓存,但仍然没有缓存

有效的修复是设置ttl:

sub vcl_backend_response {
    unset beresp.http.expires;
    unset beresp.http.pragma;
    unset beresp.http.cache-control;
    unset beresp.http.set-cookie;

    # THIS MADE VARNISH TO CACHE
    set beresp.ttl = 10m;
}

现在问题

如果默认值为2m(在下面的CLI中为-t 120)并且所有缓存清除头都需要处理,为什么我需要显式设置TTL?

/usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :80 -T 0.0.0.0:6082 -t 120 -u varnish -g varnish -S /etc/varnish/secret -s malloc,512M

我错过了什么吗?有没有不同的方法,whitout设置TTL(我更喜欢)?

1 个答案:

答案 0 :(得分:3)

问题是Varnish在调用 Expires之前评估vcl_backend_response后端响应标头。结果是传递给vcl_backend_response的对象已经有一个过期的TTL(假设标题有一个过期的日期)。下一个客户端请求将在缓存对象上命中,但是由于对象已过期(HIT-FOR-PASS),因此会丢失。是的,您要取消设置Expires标题(通过unset beresp.http.expires;),但到那时为时已晚。

现在,这是一个错误,还是Varnish开发人员对RFC的解释,我不确定。

我理解您的代码可能仅用于测试目的,但最好不要在VCL中与缓存标头作斗争。使用适当的值(session_cache_limiter()publicprivate)调用PHP的nocache,或者将其禁用(session_cache_limiter(''))并控制标题自己。

如果您正在使用PHP会话,您仍然必须处理cookie标头使其无法缓存,但这是问题范围之外的另一个问题。