实操 Web Cache
写这篇文章的原因,是我看到网上很多谈这类的文章,多是人云亦云,不求实事,误导读者。
下面文中我会一个一个做实验,并展示给你,说明为什么会这样。只有自己亲自尝试才能拿出有说服力的真凭实据。
目录
1. 测试环境
2. 文件修改日期 If-Modified-Since / Last-Modified
2.1. 静态文件
2.1.1. if_modified_since
2.2. 通过rewrite伪静态处理
2.3. 动态文件
3. ETag / If-None-Match
3.1. 静态文件
3.2. 动态程序
4. Expires / Cache-Control
4.1. 静态文件
4.2. 动态文件
5. FastCGI 缓存相关
6. HTML META 与 Cache
7. gzip
7.1. gzip 总结
8. 反向代理与缓存
8.1. gzip 处理
9. 特殊数据缓存
9.1. json
9.2. XML
10. 总结
1. 测试环境
CentOS 6.5
Nginx安装脚本 https://github.com/oscm/shell/blob/master/nginx/nginx.sh
php安装脚本 https://github.com/oscm/shell/blob/master/php/5.5.8.sh
2. 文件修改日期 If-Modified-Since / Last-Modified
If-Modified-Since 小于 Last-Modified 返回 HTTP/1.1 200 OK, 否则返回 HTTP/1.0 304 Not Modified
每次浏览器请求文件会携带 If-Modified-Since 头,将当前时间发送给服务器,与服务器的Last-Modified时间对对比,如果大于Last-Modified时间,返回HTTP/1.0 304 Not Modified不会重新打开文件,否则重新读取文件并返回内容
2.1. 静态文件
nginx/1.0.15 静态文件自动产生 Last-Modified 头
# nginx -v
nginx version: nginx/1.0.15
# curl -I http://192.168.6.9/index.html
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Thu, 27 Feb 2014 07:36:03 GMT
Content-Type: text/html
Content-Length: 6
Last-Modified: Thu, 27 Feb 2014 07:29:50 GMT
Connection: keep-alive
Accept-Ranges: bytes
图片文件
# curl -I http://192.168.6.9/image.png
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Thu, 27 Feb 2014 07:37:18 GMT
Content-Type: image/png
Content-Length: 41516
Last-Modified: Thu, 27 Feb 2014 07:36:59 GMT
Connection: keep-alive
Accept-Ranges: bytes
提示
疑问 nginx/1.4.5 默认没有 Last-Modified
# nginx -v nginx version: nginx/1.4.5 # curl -I http://192.168.2.15/index.html HTTP/1.1 200 OK Server: nginx/1.4.5 Date: Fri, 28 Feb 2014 02:13:44 GMT Content-Type: text/html Connection: keep-alive
经过一番周折最终找到答案 Nginx 如果开启 ssi 会禁用Last-Modified 关闭 ssi 后输出如下
# curl -I http://localhost/index.html HTTP/1.1 200 OK Server: nginx/1.4.5 Date: Fri, 28 Feb 2014 05:44:29 GMT Content-Type: text/html Content-Length: 6 Last-Modified: Wed, 25 Dec 2013 03:18:16 GMT Connection: keep-alive ETag: "52ba4e78-6" Accept-Ranges: bytes
再测试一次
# curl -H "If-Modified-Since: Fir, 28 Feb 2014 07:42:55 GMT" -I http://192.168.2.15/test.html
HTTP/1.1 304 Not Modified
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:34:54 GMT
Last-Modified: Fri, 28 Feb 2014 01:55:50 GMT
Connection: keep-alive
ETag: "530feca6-8b"
测试结果成功返回 HTTP/1.1 304 Not Modified, 但又莫名其妙的出现了 ETag。 这就是Nignx本版差异,非常混乱。
既然出现了ETag我们也顺便测试一下
# curl -H 'If-None-Match: "530feca6-8b"' -I http://192.168.2.15/test.html
HTTP/1.1 304 Not Modified
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:39:18 GMT
Last-Modified: Fri, 28 Feb 2014 01:55:50 GMT
Connection: keep-alive
ETag: "530feca6-8b"
也是成功的
测试图片
# curl -I http://localhost/logo.jpg
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:59:04 GMT
Content-Type: image/jpeg
Content-Length: 10103
Last-Modified: Fri, 28 Feb 2014 02:56:37 GMT
Connection: keep-alive
ETag: "530ffae5-2777"
Accept-Ranges: bytes
# curl -H 'If-None-Match: "530ffae5-2777"' -I http://localhost/logo.jpg
HTTP/1.1 304 Not Modified
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 03:03:33 GMT
Last-Modified: Fri, 28 Feb 2014 02:56:37 GMT
Connection: keep-alive
ETag: "530ffae5-2777"
# curl -H "If-Modified-Since: Fri, 28 Feb 2014 12:04:18 GMT" -I http://localhost/logo.jpg
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 03:04:45 GMT
Content-Type: image/jpeg
Content-Length: 10103
Last-Modified: Fri, 28 Feb 2014 02:56:37 GMT
Connection: keep-alive
ETag: "530ffae5-2777"
Accept-Ranges: bytes
测试结果,ETag通过测试,If-Modified-Since无论如何也无法返回 304 可能还需要其他的HTTP头,浏览器测试都通过返回 HTTP/1.1 304 Not Modified
现在换成浏览器测试 Chrome Firefox成功, 因为浏览器不会主动发送If-Modified-Since, 浏览器只有发现Last-Modified后,第二次请求才会推送 If-Modified-Since 需要刷新两次页面。
2.1.1. if_modified_since
在开启ssi的情况下,通过参数 if_modified_since 可以开启 Last-Modified
server {
listen 80;
server_name 192.168.2.15;
if_modified_since before;
}
测试结果看不到 Last-Modified, 因为 Nginx 的 if_modified_since before;参数只有接收到浏览器发过来的If-Modified-Since头才会发送Last-Modified
# curl -I http://192.168.2.15/test.html
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:39:42 GMT
Content-Type: text/html
Connection: keep-alive
最终 if_modified_since before; 数没有起到作用
参数设置为 if_modified_since exact;
# curl -I http://192.168.2.15/test.html
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:45:40 GMT
Content-Type: text/html
Connection: keep-alive
# curl -H 'If-None-Match: "530feca6-8b"' -I http://192.168.2.15/test.html
HTTP/1.1 304 Not Modified
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:45:44 GMT
Last-Modified: Fri, 28 Feb 2014 01:55:50 GMT
Connection: keep-alive
ETag: "530feca6-8b"
# curl -H "If-Modified-Since: Fir, 28 Feb 2014 07:42:55 GMT" -I http://192.168.2.15/test.html
HTTP/1.1 200 OK
Server: nginx/1.4.5
Date: Fri, 28 Feb 2014 02:45:50 GMT
Content-Type: text/html
Connection: keep-alive
测试失败,浏览器也是实测失败,ETag却成功
2.2. 通过rewrite伪静态处理
index.php仍然是上面的那个php文件,我们只是做了伪静态</