带有“Set-Cookie”标头的 Varnish 缓存响应

带有“Set-Cookie”标头的 Varnish 缓存响应

我有一个页面,它会根据 URL 发送“Set-Cookie”标头,例如语言。问题是这个页面的命中率相当高,但目前无法删除“Set-Cookie”标头,以便 Varnish 4 缓存它。

文档仅显示如何unset beresp.http.set-cookie或我可以使用将 cookie 添加到哈希中hash_data(req.http.cookie)。据我所知,将 cookie 添加到哈希仅适用于请求 Cookies,而不适用于后端设置的 cookie。

我很确定vmod_header可能是解决方案的一部分,但我如何使用它来缓存与我匹配的 cookieberesp.http.Set-Cookie == "language=en_us; path=/; domain=mydomain.tld"并缓存此响应?

答案1

缓存键(即 hash_data 中计算出的哈希值)是在接收请求时创建的。尚未收到服务器的响应。之后您无法更改它。

我能看到的两个选项是:

  • 或者禁用带有 Set-Cookie 标头的响应缓存(我认为这可能是 varnish 默认完成的)
  • 或者列出您在 Cookie 计算中使用的传入请求中的参数(url、host、accept-language……)并使用 hash_data 将它们添加到请求哈希中

答案2

我最终这样解决了这个问题:

...
# The data on which the hashing will take place
sub vcl_hash {
  hash_data(req.url);
  if (req.http.host) {
        hash_data(req.http.host);
  } else {
        hash_data(server.ip);
  }

  # If the client supports compression, keep that in a different cache
  if (req.http.Accept-Encoding) {
        hash_data(req.http.Accept-Encoding);
  }

  # We add the cookie in the mix with the hash because we actually set cr_layout
  # It should be OK in this particular instance if the number of cookies will not grow
  hash_data(req.http.Cookie);
  return (lookup);
}

# This function is used when a request is sent by our backend
sub vcl_backend_response {
  # If we find our layout cookie we copy it to a header and then we remove it so we can cache the page
  # Later after we deliver the page from cache we set the cookie from the header and then remove that header
  if ( beresp.http.Set-Cookie && beresp.http.Set-Cookie ~ "cr_layout" ) {
    set beresp.http.first-visit = beresp.http.Set-Cookie;
    unset beresp.http.Set-Cookie;
  }
}

sub vcl_deliver {
  # We found that we created a header earlier to remove the cr_layout cookie temporary
  # Now we create that cookie again and remove the header.
  if (resp.http.first-visit) {
    set resp.http.Set-Cookie = resp.http.first-visit;
    unset resp.http.first-visit;
  }
}

相关内容