因最近客戶端慢的問題,系統分析了下http協議緩存問題。本文主要記錄總結http緩存相關知識。
1. 討論涉及的要點
訪問返回類
> 訪問返回200 OK
> 訪問返回200 (from memory cache)
> 訪問返回200 (from disk cache)
> 訪問返回304 Not Modified
頭設置類
> Cache-Control: max-age=604800
> Expires: Thu, 05 Jan 2017 12:24:24 GMT
2. 測試環境1
機器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
3. 測試1 nginx直接作為后端服務器
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
4. 第一次訪問http://10.0.0.102/index.html (記得清理瀏覽器緩存)
上圖為index.html請求包
上圖為index.html響應包
上圖為1.js請求包
上圖為1.js響應包
這是index.html和1.js都返回200 ok的情況
5. 第二次訪問http://10.0.0.102/index.html 在地址欄敲回車鍵
上圖為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
6. 關於etag
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
”
7. expires和cache-control中max-age區別
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 支持
”
8. tomcat對304的處理
分析了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--










