HTTP Vary

HTTP Vary不是一个简单的概念,它是迄今为止最被误解的http头。

大量的响应头告诉客户端一些关于被传递的http对象信息。客户端可以基于其偏好,请求http对象的不同变体。他们的偏好可能会覆盖一些东西,例如encoding和language。当客户端更喜欢英式英语的话可以通过Accept-Language: en-uk来传递。缓存需要将不同的种类区分开,这是通过http响应头Vary来实现的。

当后端服务器返回Vary: Accept-Language,它告诉varnish,它需要对每一个来自客户端的Accept-Language区分对待,并缓存不同的版本。

当两个客户端分别声明他们接受的语言是“en-us, en-uk”和“da, de”,varnish将会缓存页面两个不同的版本,如果后端标识varnish需要区分Accept-Language头的话。

但是你需要注意的是,Vary需要完全匹配。因此,对于"en-us, en-uk"和"en-us,en-uk"两个头varnish将会创建并保存两个不同的版本。仅仅是因为其中一个版本中间多了一个空格。

为了在使用Vary的同时获得较高的命中率,关键是要对后端的header标准化。哪怕有一点不同,就会导致不同的缓存。

下面的VCL代码将会对Accept-Language格式标准化:

if (req.http.Accept-Language) {
    if (req.http.Accept-Language ~ "en") {
        set req.http.Accept-Language = "en";
    } elsif (req.http.Accept-Language ~ "de") {
        set req.http.Accept-Language = "de";
    } elsif (req.http.Accept-Language ~ "fr") {
        set req.http.Accept-Language = "fr";
    } else {
        # unknown language. Remove the accept-language header and
        # use the backend default.
        unset req.http.Accept-Language
    }
}

Vary格式化错误

当它格式化Vary头失败时,varnish就会返回503错误。或者客户端的头大小超过的65k,在这种情况下SLT_Error日志会被增加。

陷阱——Vary: User-Agent

一些程序或者程序服务器会与内容一起发送Vary: User-Agent头。这就会指示varnish对每个不同的User-Agent缓存不同的内容。即使是相同的浏览器,基于不同的系统、不同的版本也会有至少有10个不同的User-Agent头。

所以,如果你真的想要基于User-Agent去区分不同的内容,你最好先对头信息进行格式化,否则你的命中率将会很差劲。可以使用上面的代码作为模版进行修改。

results matching ""

    No results matching ""