清漆:如何根据特定 cookie 的值单独缓存页面

Mat*_*att 5 php cookies varnish varnish-vcl

我管理的站点只有一个 cookie,我们必须使用它,但它始终是 9 个值之一(包括没有值)。我想在我们的应用程序服务器前使用 varnish,varnish 根据 cookie 值分别缓存每个页面的一个版本。

因此,如果我们有页面 /page1,Varnish 应该单独管理 /page1 外观的副本,其中包含 cookie 值 a、b、c、d 等......

假设我们在 Varnish 服务器上有足够的内存来处理存储所有带有所有 cookie 组合的页面。

我们已经尝试了许多 VCL 设置,但无法确切地弄清楚如何进行这项工作。Varnish 还需要将该特定 cookie 发送到我们的应用程序服务器,以便我们的应用程序知道要发送回哪些内容。

提前致谢!

NIT*_*MAN 5

事实上,实现起来非常简单,您应该添加一个自定义vcl_hash

sub vcl_hash {
  #...
  /* Hash cookie data */
  # As requests with same URL and host can produce different 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);
  }
  #...
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,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);
  #...
}
Run Code Online (Sandbox Code Playgroud)

[1] https://github.com/NITEMAN/varnish-bites/blob/master/varnish3/drupal-base.vcl