实际上,您应该添加一个自定义项,这很简单vcl_hash
:
sub vcl_hash {
#...
/* Hash cookie data */
# As requests with same URL and host can produce diferent results when issued with different cookies,
# we need to store items hashed with the associated cookies. Note that cookies are already sanitized when we reach this point.
if (req.http.Cookie) {
/* Include cookie in cache hash */
hash_data(req.http.Cookie);
}
#...
}
使用此代码,varnish 将为每个 cookie 值存储一个不同的 cookie...但我建议您也对 cookie 进行清理vcl_recv
,这是 [1] 的摘录,其中包含 Drupal 站点的 cookie 清理:
sub vcl_recv {
#...
# Remove all cookies that backend doesn't need to know about.
# See https://www.varnish-cache.org/trac/wiki/VCLExampleRemovingSomeCookies
if (req.http.Cookie) {
/* Warning: Not a pretty solution */
/* Prefix header containing cookies with ';' */
set req.http.Cookie = ";" + req.http.Cookie;
/* Remove any spaces after ';' in header containing cookies */
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
/* Prefix cookies we want to preserve with one space */
/* 'S{1,2}ESS[a-z0-9]+' is the regular expression matching a Drupal session cookie ({1,2} added for HTTPS support) */
/* 'NO_CACHE' is usually set after a POST request to make sure issuing user see the results of his post */
/* Keep in mind we should add here any cookie that should reach the backend such as splahs avoiding cookies */
set req.http.Cookie = regsuball(req.http.Cookie, ";(S{1,2}ESS[a-z0-9]+|NO_CACHE|OATMEAL|CHOCOLATECHIP)=", "; \1=");
/* Remove from the header any single Cookie not prefixed with a space until next ';' separator */
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
/* Remove any '; ' at the start or the end of the header */
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
/* If there are no remaining cookies, remove the cookie header. */
unset req.http.Cookie;
}
}
#...
return(hash);
#...
}
[1] https://github.com/NITEMAN/varnish-bites/blob/master/varnish3/drupal-base.vcl