因最近客户端慢的问题,系统分析了下http协议缓存问题。本文主要记录总结http缓存相关知识。javascript
访问返回类html
> 访问返回200 OKjava
> 访问返回200 (from memory cache)nginx
> 访问返回200 (from disk cache)web
> 访问返回304 Not Modifiedchrome
头设置类ubuntu
> Cache-Control: max-age=604800 后端
> Expires: Thu, 05 Jan 2017 12:24:24 GMT 浏览器
机器A做为客户端,IP: 10.0.0.2 chrome 版本 55.0.2883.87 m 缓存
机器B做为服务断, IP: 10.0.0.102 nginx 1.1.19 ubuntu 12.04
1) 修改nginx的配置文件
location / { # First attempt to serve request as file, then # as directory, then fall back to index.html try_files $uri $uri/ /index.html; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules expires 7d; }
增长了expires 7d;
2) 修改index.html
<html> <head> <title>Welcome to nginx!</title> <script type="text/javascript" src="1.js"></script> </head> <body bgcolor="white" text="black"> <center><h1>Welcome to nginx!123456</h1></center> <a href="1.txt">1.txt</a> </body> </html>
增长一个引入js 1.js
增长一个超连接1.tx
上图为index.html请求包
上图为index.html响应包
上图为1.js请求包
上图为1.js响应包
这是index.html和1.js都返回200 ok的状况
上图为index.html请求包
上图为index.html响应包,此时 回 304 Not Modified ,而且服务器仅仅是回了状态码,没有将index.html数据写回客户端。
从整个抓包来看,没有看到1.js的请求包,证实此时针对1.js这个文件 连http请求都没有发。
再经过那个超连接作实验发现和1.js同样的结论,第一次回200 OK 第二次以后就会200 from xxx cache
cache有memory和disk之分,这个很好理解。
在已经缓存了的状况下:
在地址栏敲回车,是回304 。 被别人引用或者点击超连接时,回 200 form xxx cache
参考 http://guojianxiang.com/posts/2015-09-01-About_HttpStatus200_FromCache_And_304_NotModified.html 弯路2
nginx默认不支持etag, 能够使用插件完成。
nginx做者对其解释,参考 http://blog.csdn.net/21aspnet/article/details/6604805
“
Nginx中默认没有添加对Etag标识.Igor Sysoev的观点”在对静态文件处理上看不出如何Etag好于Last-Modified标识。”
Note:
Yes, it's addition,and it's easy to add, however, I do not see howETag is better than Last-Modified for static files. -Igor Sysoev
A nice short description is here:
http://www.mnot.net/cache_docs/#WORK
”
nginx是在后台指定expires的间隔(好比7天后超期),而后nginx会自动在http头中转换成max-gae的时间,和头中Expires会变换成具体的超期时刻(不是间隔了)
参考 https://www.bokeyy.com/post/high-performance-web-sites-rule3.html
“
Max-age:在 HTTP 头中按秒指定失效的时间,以下图。好处是不像方法 1(expries) 同样须要定时检查是否过时,一旦过时就须要指定新的时间,坏处是只有 HTTP/1.1 支持
”
分析了tomcat6 阅读其代码 一目了然
protected boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response, ResourceAttributes resourceAttributes) throws IOException { try { long headerValue = request.getDateHeader("If-Modified-Since"); long lastModified = resourceAttributes.getLastModified(); if (headerValue != -1) { // If an If-None-Match header has been specified, if modified since // is ignored. if ((request.getHeader("If-None-Match") == null) && (lastModified < headerValue + 1000)) { // The entity has not been modified since the date // specified by the client. This is not an error case. response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.setHeader("ETag", resourceAttributes.getETag()); return false; } } } catch (IllegalArgumentException illegalArgument) { return true; } return true; }
HttpServletResponse.SC_NOT_MODIFIED 就是304状态
resourceAttributes.getLastModified(); 读取文件上次修改时间。
有兴趣的话能够继续分析tomcat对etag的处理。
--EOF--