使用Cookie标头使Varnish忽略请求

Alb*_*dez 6 cookies http varnish browser-cache varnish-vcl

清漆默认行为是永远不会查找包含Cookie标头的请求.换句话说,Cookie永远不会缓存包含标头的请求.我需要覆盖此行为以忽略带有Cookie标头的请求.

考虑我的应用程序中的下一个用户行为:

  1. 用户进入应用程序主页(/),页面应该被缓存,后端返回public缓存控件,一切都很好,页面被Varnish缓存.
  2. 用户导航到/not-cacheable不可缓存的自定义页面(),后端返回private缓存控件.还会Set-Cookie在响应中返回标头.Varnish忽略了这个请求,用户最终得到了一个cookie.到现在为止还挺好.
  3. 用户导航回主页(/),记住,已经缓存了.问题是,用户请求现在带有Cookie标题.这会导致Varnish忽略该请求并委托给后端.

删除Cookie 将不起作用,因为当用户返回/not-cacheable路线时,他将看不到他的个性化页面,因为Cookie标题已被条带化.相反,后端返回一个新生成的会话,其中包含一个新的id Set-Cookie.

此外,Cookie在Varnish中查找每个请求都会导致每个请求(有关方法或后端响应)被缓存.

如果有一种方法告诉Varnish只是忽略Cookie标头,这样我就可以通过让后端决定请求是否可以缓存来缓存具有该标头的请求.

有任何想法吗?

Alb*_*dez 1

仅供记录,我最终想出了一个 VCL 脚本,它使用自定义标头并重新启动请求来解决此问题:

backend default
{
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv
{
    if(req.http.X-Force-Backend)
    {
        return(pass);
    }

    if(req.http.Cookie && req.request ~ "(GET|HEAD)")
    {
        set req.http.X-Cookie = req.http.Cookie;
        remove req.http.Cookie;

        return(lookup);
    }
}

sub vcl_deliver
{
    if(resp.http.Cache-control ~ "(private|no-cache|no-store)" 
        && !req.http.X-Force-Backend
        && req.request ~ "(GET|HEAD)"
    )
    {
        set req.http.X-Force-Backend = "YES";
        set req.http.Cookie = req.http.X-Cookie;

        remove req.http.X-Cookie;

        return(restart);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Cookie当我们从后端收到不可缓存的响应时,通过始终删除标头并重新启动请求,我们可以达到预期的效果。我不知道可能存在的性能缺陷,但我在生产中使用它并且效果很好。

我还写了一篇关于这个具体问题的博客文章,如果有人也使用 Symfony 和 Varnish,它可能会很有趣:http://albertofem.com/post/symfony-varnish-and-http-practical-considerations.html