最近發現自己學習的東西太雜,不成系統,所以準備整理後再出發。整理也是一種昇華。在學習的路上多總結,感覺很好!
這裏從緩存開始說起,好久都沒有寫什麼博客了,內容有不對的地方歡迎指正
好像大多問題都能通過加緩存解決,什麼叫緩存呢,緩存就是把需要花費昂貴開銷的計算結果保存起來,在之後訪問直接取出,這個昂貴的開銷可以是昂貴的計算,也可以是昂貴的帶寬費用等等
從client端出發,首先來說說瀏覽器緩存,也許從某種角度上看,瀏覽器也是一個web服務器,也能算一級緩存,內部也存在的各種緩存協商的過程
last-modified
原理
這個從名字上就基本上能瞭解他是什麼呢,最後一次修改時間,
流程圖:
第一次訪問的時候,web服務端首次返回給client端last-modified最後一次修改時間,然後再一次訪問的時候,client請求頭中就會以if-modified-since帶入最後一次修改時間,用戶詢問web服務端,在這個時間之後有沒有做過修改,如果沒有,直接本地返回304狀態,如果做了修改,從web服務端直接返回給用戶,用戶本地保存一份,然後下次已經這一次最後的修改時間爲準!這個還是比較好理解!
配置
Apache last-modified是默認開啓的
模塊爲:mod_headers.so
關閉方法
要關掉Last-Modified的方法麻煩點,先想好你要去掉Last-Modified 的標籤.然後用header模塊來控制
LoadModule headers_module modules/mod_headers.so <FilesMatch "\.(gif|jpg|png)"> Header unset Last-Modified < /FilesMatch>
不足
1、last-modified只能精確到秒,如果在秒內做了修改,是檢測不到
2、如果是集羣環境的話,相同文件的last-modified可能會不相同的,用戶可能要緩存獲取兩次
3、不管你的內容有沒有真正的修改
暫時只知道這幾點不足
ETag
原理
ETag:網上的有很正確的理解,我個人的理解是在client端發起訪問的時候,web服務端會在返回頭中帶入資源的ETag值(通過算法對內容進行一個計算得出的一個唯一id)客戶端緩存這個資源,然後這個ETag值也會被保存,在再一次請求相同資源的時候,瀏覽器會把第一次服務端返回過來的值帶入請求頭中(if-none-match)如果服務端內容沒有表換就返回304如果有變化就返回200內容從服務端返回,如果跟last-modified一起使用的話ETag優先級高於last-modified
配置
Apache
apache 默認開啓Etag
格式:apache Etag由inode+大小+時間戳
關閉方式:
FileETag None
Header unset ETag
Header unset Last-Modified
nginx默認沒有這個模塊,需要重新編譯進去
不足
1、沒有進行實際的測試,感覺如果文件多了,大了,還有如果自己寫的算法爛也會影響性能
expires
原理
這個最吊,直接可以不用跟web服務端進行緩存協商,本地協商就能完成,web服務端中返回head中帶入過期時間,然後瀏覽器每一次只需要date與expires進行比較就好,如果過期就去服務端獲取,如果沒有過期就本地返回!
配置
Apache是通過expires模塊實現
格式:
ExpiresActive on
ExpiresByType image/gif “access plus 1 month”
ExpiresByType image/jpg “access plus 1 month”
ExpiresByType image/jpeg “access plus 1 month”
。。。。。
nginx上面默認有的並開啓狀態
格式:
location ~ .*\.(js|css)?$
{
expires 1h;
}
不足:
1、expires受服務端跟client端時間影響,如果客戶端時間如果慢了還是快了都會影響緩存的有效行,而客戶端時間這種不可控的信息我們不能去實現時間一致
因爲expires的不足,cache-control出來了
cache-control
原理
cache-control跟expires一樣都是說明資源的一個有效時間,而不通的在於是expires是date時間到服務端給出的時間的一個有效時間,cache-control有效時間是client訪問web服務端之後開始計算的一個時間內。如果max-ago=60 就是第一次訪問後的60後資源過期,這樣子就去除了expires依賴client時間的弊端,如果expires與cache-control同時存在,cache-control的優先級高於expires
nginx配置
if ($request_uri ~* "^/$|^arch/.+/|^/company/.+/") {
add_header Cache-Control max-age=3600;
}
if ($request_uri ~* "^arch-suggest/|^/categories/") {
add_header Cache-Control max-age=86400;
}
小注釋:
瀏覽器的三種刷新方式:
使用瀏覽器的轉到按鈕、或者在地址欄直接回車、或者打開新窗口重新輸入該網址
優先走瀏覽器本地緩存,如果本地有緩存則根本不會訪問服務器
注:如果是chrome下,在本窗口下的地址欄直接回車,html不會走本地緩存,如果是新開窗口在地址欄輸入網址回車,則html依然會走本地緩存。估計是chrome的策略,firefox下則都會走本地緩存
使用瀏覽器的刷新按鈕、F5刷新或者是Mac Chrome下的Command + r刷新
不走瀏覽器本地緩存,不過會走服務端緩存,會返回304
使用瀏覽器的強制刷新,如Ctrl+ F5或者是Mac Chrome下的Command + Shift + r
既不走瀏覽器本地緩存,也不走服務端緩存,不返回304
無法被瀏覽器緩存的請求:
HTTP信息頭中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告訴瀏覽器不用緩存的請求
需要根據Cookie,認證信息等決定輸入內容的動態請求是不能被緩存的
經過HTTPS安全加密的請求(有人也經過測試發現,ie其實在頭部加入Cache-Control:max-age信息,firefox在頭部加入Cache-Control:Public之後,能夠對HTTPS的資源進行緩存,參考《HTTPS的七個誤解》)
POST請求無法被緩存
HTTP響應頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被緩存