瀏覽器緩存
200 from memory cache 不訪問服務(wù)器,直接讀緩存香罐,從內(nèi)存中讀取緩存。此時的數(shù)據(jù)時緩存到內(nèi)存中的时肿,當(dāng)kill進(jìn)程后,也就是瀏覽器關(guān)閉以后港粱,數(shù)據(jù)將不存在螃成。但是這種方式只能緩存派生資源
200 from disk cache 不訪問服務(wù)器,直接讀緩存查坪,從磁盤中讀取緩存寸宏,當(dāng)kill進(jìn)程時,數(shù)據(jù)還是存在偿曙。這種方式也只能緩存派生資源
304 Not Modified 訪問服務(wù)器氮凝,發(fā)現(xiàn)數(shù)據(jù)沒有更新,服務(wù)器返回此狀態(tài)碼望忆。然后從緩存中讀取數(shù)據(jù)罩阵。
三級緩存原理
- 先去內(nèi)存看,如果有启摄,直接加載
- 如果內(nèi)存沒有稿壁,擇取硬盤獲取,如果有直接加載
- 如果硬盤也沒有歉备,那么就進(jìn)行網(wǎng)絡(luò)請求
- 加載到的資源緩存到硬盤和內(nèi)存
一般瀏覽圖片傅是,如下流程:
- 訪問-> 200 -> 退出瀏覽器
- 再進(jìn)來-> 200(from disk cache) -> 刷新 -> 200(from memory cache)
application cache和上面緩存有點區(qū)別,是離線緩存,就是資源可以從硬盤上讀取而不用聯(lián)網(wǎng)喧笔,即使斷網(wǎng)帽驯,用戶也可以瀏覽。
設(shè)置瀏覽器緩存
304是協(xié)商緩存還是要和服務(wù)器通信一次书闸,要想斷絕服務(wù)器通信尼变,就要強制瀏覽器使用本地緩存(cache-control/expires),
一般有如下幾種方式設(shè)置瀏覽器緩存梗劫。
1享甸、通過HTTP的META設(shè)置expires和cache-control
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Sun Oct 15 2017 20:39:53 GMT+0800 (CST)" />
2、apache服務(wù)器配置圖片梳侨,css蛉威,js,flash的緩存
這個主要通過服務(wù)器的配置來實現(xiàn)這個技術(shù)走哺,如果使用apache服務(wù)器的話蚯嫌,可以使用mod_expires模塊來實現(xiàn):
編譯mod_expires模塊:
Cd /root/httpd-2.2.3/modules/metadata
/usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯
先打開httpd.conf文件,然后查找expires這個模塊丙躏,找到后择示,刪除左邊的#號,表示打這個模塊晒旅,并重啟apache服務(wù)器
編輯httpd.conf配置:添加下面內(nèi)容
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 1 months"
ExpiresByType text/css "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
EXpiresByType application/x-shockwave-flash "access plus 1 months"
EXpiresByType application/x-javascript "access plus 1 months"
#ExpiresByType video/x-flv "access plus 1 months"
</IfModule>
3栅盲、php等設(shè)置
<?php
header("Cache-Control: public");
header("Pragma: cache");
$offset = 30*60*60*24; // cache 1 month
$ExpStr = "Expires: ".gmdate("D, d M Y H:i:s", time() + $offset)." GMT";
header($ExpStr);
?>
或者
$seconds_to_cache = 3600;
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts"); header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
緩存情況下前端代碼部署
問題一:有了緩存,如何進(jìn)行前端代碼更新呢废恋?
我們可以在資源文件或者圖片后面添加版本號谈秫,如下圖。問題二:但是所有文件都加了版本號之后鱼鼓,我們只更改了一個文件拟烫,其他文件的緩存不是浪費了嗎?**
解決這個問題迄本,我們可以用 數(shù)據(jù)摘要要算法硕淑,對文件求摘要信息,摘要信息與文件內(nèi)容一一對應(yīng)嘉赎。如下圖:問題三:新的問題又來了置媳,文件發(fā)布怎么辦?
1公条、先部署頁面半开,再部署資源:在二者部署的時間間隔內(nèi),如果有用戶訪問頁面赃份,就會在新的頁面結(jié)構(gòu)中加載舊的資源寂拆,并且把這個舊版本的資源當(dāng)做新版本緩存起來奢米,其結(jié)果就是:用戶訪問到了一個樣式錯亂的頁面,除非手動刷新纠永,否則在資源緩存過期之前鬓长,頁面會一直執(zhí)行錯誤。
2尝江、先部署資源涉波,再部署頁面:在部署時間間隔之內(nèi),有舊版本資源本地緩存的用戶訪問網(wǎng)站炭序,由于請求的頁面是舊版本的啤覆,資源引用沒有改變,瀏覽器將直接使用本地緩存惭聂,這種情況下頁面展現(xiàn)正常窗声;但沒有本地緩存或者緩存過期的用戶訪問網(wǎng)站,就會出現(xiàn)舊版本頁面加載新版本資源的情況辜纲,導(dǎo)致頁面執(zhí)行錯誤笨觅,但當(dāng)頁面完成部署,這部分用戶再次訪問頁面又會恢復(fù)正常了耕腾。
好的见剩,上面一坨分析想說的就是:先部署誰都不成!都會導(dǎo)致部署過程中發(fā)生頁面錯亂的問題扫俺。所以苍苞,訪問量不大的項目,可以讓研發(fā)同學(xué)苦逼一把狼纬,等到半夜偷偷上線柒啤,先上靜態(tài)資源,再部署頁面畸颅,看起來問題少一些。如何解決這些問題呢方援?
這個問題没炒,起源于資源的 覆蓋式發(fā)布,用 待發(fā)布資源 覆蓋 已發(fā)布資源犯戏,就有這種問題送火。解決它也好辦,就是實現(xiàn) 非覆蓋式發(fā)布先匪,如下圖:
看上圖种吸,用文件的摘要信息來對資源文件進(jìn)行重命名,把摘要信息放到資源文件發(fā)布路徑中呀非,這樣坚俗,內(nèi)容有修改的資源就變成了一個新的文件發(fā)布到線上镜盯,不會覆蓋已有的資源文件。上線過程中猖败,先全量部署靜態(tài)資源速缆,再灰度部署頁面,整個問題就比較完美的解決了恩闻。
總結(jié)如下:
1艺糜、 配置超長時間的本地緩存 —— 節(jié)省帶寬,提高性能
2幢尚、采用內(nèi)容摘要作為緩存更新依據(jù) —— 精確的緩存控制
3破停、 靜態(tài)資源CDN部署 —— 優(yōu)化網(wǎng)絡(luò)請求
4、更資源發(fā)布路徑實現(xiàn)非覆蓋式發(fā)布 —— 平滑升級