首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Varnish:如何根据特定cookie的值分别缓存页面

Varnish:如何根据特定cookie的值分别缓存页面
EN

Stack Overflow用户
提问于 2013-09-28 03:29:31
回答 2查看 5K关注 0票数 5

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

因此,如果我们有页面/page1,Varnish应该单独管理/page1的副本和Cookie值a、b、c、d等。

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

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

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2013-09-28 23:22:44

实际上,要实现这一点非常简单,您应该添加一个自定义vcl_hash

代码语言:javascript
复制
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 ...但我建议你也在vcl_recv上清理你的cookie,这是一段摘录,其中包含了针对Drupal站点的cookie清理:

代码语言:javascript
复制
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

票数 4
EN

Stack Overflow用户

发布于 2019-07-27 10:20:42

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

来自自述文件中的示例(稍作调整):

代码语言:javascript
复制
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);
        # ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19058660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档