当使用错误的大写字母访问某些文件时,Varnish 不会缓存它们

当使用错误的大写字母访问某些文件时,Varnish 不会缓存它们

我们在一堆 IIS 服务器前面安装了 Varnish 3.0.6。

IIS 服务器不关心传入请求的大小写,尽管我不断提醒开发人员,但他们当然在所有代码中使用 RandomCase。我以为这会导致最糟糕的结果就是缓存中的资源重复,然而我们看到的是 Varnish 在某些情况下根本不缓存。

我有一个网址,例如http://www.example.com/Content/images/flags/gb.png

我在 VCL 中设置了一个标头,以告诉我该请求在 Varnish 中是命中还是未命中,如果我curl从某处使用该标头几次命中,我就会得到我期望的命中:

$ curl -Ss -X GET 'http://10.0.0.1/Content/images/flags/gb.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: HIT 15 Var01

但是,如果我使用的 URL 的大小写不正确,无论我获取多少次,都会得到 MISS 的结果:

$ curl -Ss -X GET 'http://10.0.0.1/content/images/flags/gb.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: MISS Var01

奇怪的是,如果文件名路径是错误的,缓存:

$ curl -Ss -X GET 'http://10.0.0.1/content/images/flags/GB.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: HIT 15 Var01

因此看起来,如果路径和文件都正确,或者都不正确,它就会被缓存,但如果一个正确,一个不正确,它就会被缓存,绝不已缓存。


$curl -Ss -X GET 'http://10.0.0.1/content/images/flags/gb.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: MISS Var01

$curl -Ss -X GET 'http://10.0.0.1/content/images/flags/GB.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: HIT 7 Var01

$curl -Ss -X GET 'http://10.0.0.1/Content/images/flags/gb.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: HIT 7 Var01

$curl -Ss -X GET 'http://10.0.0.1/Content/images/flags/GB.png' --header 'Host: www.example.com' -I | grep X-Cache
X-Cache: MISS Var01

varnishlog以下是“缺失”请求的输出示例:

168 SessionOpen  c 192.168.0.1 60412 :80
168 ReqStart     c 192.168.0.1 60412 96071146
168 RxRequest    c GET
168 RxURL        c /content/images/flags/gb.png
168 RxProtocol   c HTTP/1.1
168 RxHeader     c User-Agent: curl/7.35.0
168 RxHeader     c Accept: */*
168 RxHeader     c Host: www.example.com
168 RxHeader     c X-Forwarded-Proto: https
168 VCL_call     c recv
168 VCL_return   c lookup
168 VCL_call     c hash
168 Hash         c /content/images/flags/gb.png
168 Hash         c www.example.com
168 VCL_return   c hash
168 HitPass      c 95565251
168 VCL_call     c pass pass
168 Backend      c 236 my_director web08
168 TTL          c 96071146 RFC 120 -1 -1 1462797933 0 1462797954 0 0
168 VCL_call     c fetch
168 TTL          c 96071146 VCL 28800 -1 -1 1462797933 -0
168 VCL_return   c deliver
168 ObjProtocol  c HTTP/1.1
168 ObjResponse  c OK
168 ObjHeader    c Content-Type: image/png
168 ObjHeader    c Last-Modified: Wed, 04 May 2016 07:56:47 GMT
168 ObjHeader    c Accept-Ranges: bytes
168 ObjHeader    c ETag: "809d381daa5d11:0"
168 ObjHeader    c Server: Microsoft-IIS/8.5
168 ObjHeader    c X-Powered-By: ASP.NET
168 ObjHeader    c Date: Mon, 09 May 2016 12:45:54 GMT
168 ObjHeader    c Content-Length: 599
168 ObjHeader    c X-Backend: web08
168 VCL_call     c deliver
168 VCL_return   c deliver
168 TxProtocol   c HTTP/1.1
168 TxStatus     c 200
168 TxResponse   c OK
168 TxHeader     c Content-Type: image/png
168 TxHeader     c Last-Modified: Wed, 04 May 2016 07:56:47 GMT
168 TxHeader     c Accept-Ranges: bytes
168 TxHeader     c ETag: "809d381daa5d11:0"
168 TxHeader     c X-Backend: web08
168 TxHeader     c Content-Length: 599
168 TxHeader     c Accept-Ranges: bytes
168 TxHeader     c Date: Mon, 09 May 2016 12:45:32 GMT
168 TxHeader     c Age: 0
168 TxHeader     c Connection: keep-alive
168 TxHeader     c X-Cache: MISS Var01
168 Length       c 599
168 ReqEnd       c 96071146 1462797932.596346378 1462797932.619358778 0.000039339 0.022963524 0.000048876

更新:更令人困惑的是,我们在这里运行的另一个网站(也是基于 IIS 的)没有出现此问题,所以我怀疑有些奇怪的事情发生了,但我不知道在哪里。我看不出 Varnish 可能看到了什么,让它认为这些请求是 MISSes - 它看到的只是 URL,因为我的vcl_hash只是hash_data(req.url);hash_data(req.http.host)

答案1

如果 Varnish 后面的所有服务器都是 IIS,那么以下内容应该可以帮助您解决此问题。

import std;
...
sub vcl_recv {
       set req.url = regsub(req.url, "\?.*", "");
       ...   
    }
...

这样,您就不必在每个表达式中使用 (?i) 进行正则表达式不区分大小写的匹配。

相关内容