簡體   English   中英

Varnish:如何根據特定cookie的值單獨緩存頁面

[英]Varnish: how to separately cache pages based on value of a specific cookie

我管理的網站只有一個cookie,我們必須使用它,但總是9個值之一(包括沒有值)。 我想在我們的應用程序服務器前面使用清漆,varnish根據cookie值分別緩存每個頁面的版本。

因此,如果我們有page / page1,Varnish應該單獨管理/ page1與cookie值a,b,c,d等相似的副本....

假設我們在Varnish服務器上有足夠的內存來處理存儲所有cookie組合的所有頁面。

我們已經嘗試了很多VCL設置,但無法弄清楚如何使其工作。 Varnish也需要將特定的cookie發送到我們的應用服務器,因此我們的應用程序知道要發回哪些內容。

提前致謝!

實現起來很簡單,實際上,你應該添加一個自定義的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);
  }
  #...
}

使用此代碼,清漆將為每個cookie值存儲不同的cookie ...但我建議您還要在vcl_recv上清理您的cookie,這是[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

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);
        # ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM