简体   繁体   English

使用Cookie标头使Varnish忽略请求

[英]Make Varnish ignore requests with Cookie header

Varnish default behaviour is to never lookup for requests containing a Cookie header. 清漆默认行为是永远不会查找包含Cookie标头的请求。 In other words, a request containing a Cookie header will never be cached. 换句话说,永远不会缓存包含Cookie标头的请求。 I need to override this behaviour to just ignore requests with a Cookie header. 我需要覆盖此行为以忽略具有Cookie标头的请求。

Consider the next user behaviour in my application: 考虑我的应用程序中的下一个用户行为:

  1. User enters application home page ( / ), page should be cached, backend returns a public cache-control, everything is fine, page gets cached by Varnish. 用户进入应用程序主页( / ),页面应该被缓存,后端返回一个public缓存控件,一切都很好,页面被Varnish缓存。
  2. User navigates to a custom page ( /not-cacheable ) which is not cacheable, backend returns a private cache-control. 用户导航到/not-cacheable的自定义页面( /not-cacheable ),后端返回private缓存控件。 Also returns a Set-Cookie header in the response. 还在响应中返回Set-Cookie标头。 Varnish ignores this request and the user ends up with a cookie. Varnish忽略了这个请求,用户最终得到了一个cookie。 So far so good. 到现在为止还挺好。
  3. User navigates back to the home page ( / ), which, remember, is already cached. 用户导航回主页( / ),记住,已经缓存了主页。 Problem is, the user request now carries a Cookie header. 问题是,用户请求现在带有Cookie标头。 This causes Varnish to ignore the request and delegate to the backend. 这会导致Varnish忽略该请求并委托给后端。

Deleting the Cookie won't work because when the user returns to the /not-cacheable route, he won't see his personalized page, as the Cookie header has been striped out. 删除Cookie 将不起作用,因为当用户返回/not-cacheable路由时,他将看不到他的个性化页面,因为Cookie标头已被条带化。 Instead, the backend returns a newly generated session with a new id in the Set-Cookie . 相反,后端返回一个新生成的会话,其中包含Set-Cookie的新ID。

Also, having every Cookie request to lookup in Varnish caused every request, regarding the method, or the backend response, to be cached. 此外,让每个Cookie请求在Varnish中查找都会导致每个请求(有关方法或后端响应)被缓存。

If there was some way of telling Varnish to just ignore the Cookie header, this way I could cache requests with that header, by letting the backend decide if the request should be cacheable or not. 如果有一种方式告诉Varnish只是忽略Cookie标头,这样我就可以通过让后端决定请求是否应该是可缓存的来缓存具有该标头的请求。

Any ideas? 有任何想法吗?

Just for the record, I finally came up with a VCL script that solves this problem using custom headers and restarting the request: 为了记录,我终于想出了一个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);
    }
}

As you can see, by always deleting the Cookie header and restarting the request when we have a non-cacheable response from the backend, we can achieve the desired effect. 如您所见,通过始终删除Cookie标头并在我们从后端获得不可缓存的响应时重新启动请求,我们可以实现所需的效果。 I don't know about possible performance drawbacks, but I'm using it in production and it works quite well. 我不知道可能的性能缺点,但我在生产中使用它并且它工作得很好。

I also wrote a blog post about this specific problem, if anyone is using Symfony and Varnish aswell, it might be interesting: http://albertofem.com/post/symfony-varnish-and-http-practical-considerations.html 我还写了一篇关于这个特定问题的博客文章,如果有人使用Symfony和Varnish,它可能会很有趣: http//albertofem.com/post/symfony-varnish-and-http-practical-considerations.html

I think removing the cookie header in the vcl_recv should do the trick, here's something I've used on my wordpress to ignore front end but not backend, you can easily remove the if condition to make it over the whole server 我认为删除vcl_recv的cookie头应该可以解决问题,这是我在wordpress上用来忽略前端而不是后端的东西,你可以轻松删除if条件使其在整个服务器上运行

sub vcl_recv {
  if (req.url !~ "^/wp-"){
    unset req.http.cookie;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM