5

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

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

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

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

提前致谢!

4

2 回答 2

4

实际上,您应该添加一个自定义项,这很简单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

于 2013-09-28T15:22:44.130 回答
0

NITEMAN在最初提出这个问题时提供了一个很好的答案。然而,中间的时间跨度导致了官方支持的 VMOD,它使过滤不需要的 cookie 变得更容易和更清洁。它可以在以下位置找到:https ://github.com/varnish/varnish-modules

从 README 中的示例(稍作调整):

import cookie;

sub vcl_recv {
        cookie.parse(req.http.cookie);
        cookie.filter_except("SESSIONID,PHPSESSID");
        set req.http.cookie = cookie.get_string();
        # Only SESSIONID and PHPSESSID are left in req.http.cookie at this point.
        # ...
        return (hash);
        # ...
}
于 2019-07-27T02:20:42.160 回答