Web快取技術相關簡析

2021-06-05 13:27:33 字數 2646 閱讀 6834

web快取最權威的資料就屬rfc了,可惜它太過言簡意賅,本文將對快取做一些通俗易懂的介紹。

expires / cache-control:

當伺服器發出響應的時候,可以通過兩種方式來告訴客戶端快取請求:

第一種是expires,比如:

expires: sun, 16 oct 2016 05:43:02 gmt

在此日期之前,客戶端都會認為快取是有效的。

不過expires有缺點,比如說,服務端和客戶端的時間設定可能不同,這就會使快取的失效可能並不能精確的按伺服器的預期進行。

第二種是cache-control,比如:

cache-control: max-age=315360000

這裡宣告的是乙個相對的秒數,表示從現在起,315360000秒內快取都是有效的,這樣就避免了服務端和客戶端時間不一致的問題。

但是cache-control是http1.1才有的,不適用與http1.0,而expires既適用於http1.0,也適用於http1.1,所以說在大多數情況下同時傳送這兩個頭會是乙個更好的選擇,當客戶端兩種頭都能解析的時候,會優先使用cache-control。

參考apache相關文件

條件get:last-modified / if-modified-since和etag / if-none-match

last-modified / if-modified-since

last-modified是響應頭,if-modified-since是請求頭。last-modified把web元件的最後修改時間告訴客戶端,客戶端在下次請求此web元件的時候,會把上次服務端響應的最後修改時間作為if-modified-since的值傳送給伺服器,伺服器可以通過這個值來判斷是否需要重新傳送,如果不需要,就簡單的傳送乙個304狀態碼,客戶端將從快取裡直接讀取所需的web元件。

etag / if-none-match

etag是響應頭,if-none-match是請求頭。last-modified / if-modified-since的主要缺點就是它只能精確到秒的級別,一旦在一秒的時間裡出現了多次修改,那麼last-modified / if-modified-since是無法體現的。相比較,etag / if-none-match沒有使用時間作為判斷標準,而是使用乙個特徵串。etag把web元件的特徵串告訴客戶端,客戶端在下次請求此web元件的時候,會把上次服務端響應的特徵串作為if-none-match的值傳送給服務端,服務端可以通過這個值來判斷是否需要從重新傳送,如果不需要,就簡單的傳送乙個304狀態碼,客戶端將從快取裡直接讀取所需的web元件。

一些建議:

當使用expires / cache-control的時候,盡量給,樣式表,指令碼等設定乙個足夠大的快取時間,如果在此期間,快取檔案有過修改,最簡單的更新方式是改名或者設定乙個查詢引數,比如開始名是logo.gif,如果做了乙個新的,你想更新,可以把改名為logo_v2.gif,或者給設定乙個查詢引數logo.gif?foobar,這樣,瀏覽器就會去請求新的了。不過,並不是所有的web元件都適合有乙個大的快取時間,比如html,就不適合使用過大的快取時間,否則你在快取到期前,就沒機會更新任何東西了。

使用yslow的都知道,它不建議使用etag,理由是etag在分布式環境裡,會給伺服器造成不必要的壓力,比如說在apache裡,etag預設是由三個因素決定的:inode size mtime,而同乙個,在不同伺服器上的inode是不同的,所以在兩個伺服器上先後請求同乙個,會得到兩次200,雖然我們可以通過設定fileetag size mtime來遮蔽inode,從而達到一次200,一次304的效果,但304也是要通過一次條件get請求驗證的,所以說,還是通過expires / cache-control來設定乙個足夠大的快取時間更划算一些,如此說來,對,樣式表,指令碼等靜態內容而言,設定乙個大的過期時間是絕對必要的,而etag和last-modified則不是必要的。

如果你決定禁止etag的話,簡單的使用fileetag none就能達到目的。

如果你想把last-modified也禁止的話,似乎沒有直接的方法,只能通過header模組的方式:

loadmodule headers_module modules/mod_headers.so

header unset last-modified

不理解快取可能會讓我們作出很多錯誤的判斷,比如說很多人在估算頻寬的時候一般是按照如下的流程來計算頻寬的(以每天百萬訪問量為例來說明):

如果100萬pv的訪問量在一天內平均分布的話,折合到每秒大約12次訪問,如果按平均每次訪問頁面的大小是100k位元組左右計算的話,這12次訪 問總計大約就是1200k位元組,位元組的單位是byte,而頻寬的單位是bit,它們之間的關係是1byte = 8bit,所以1200k byte大致就相當於9600k bit,也就是9mbps的樣子,實際情況中,我們的**必須能在峰值流量時保持正常訪問,假設峰值流量是平均流量的5倍,於是得出真實頻寬的需求應該在45mbps 左右。

如上的計算只在一種情況下是正確的,那就是**伺服器關閉了快取或者**的瀏覽者關閉了快取!不過現實情況我們出於效能的考慮肯定要加入快取,使用者在有快取的情況下產生的流量要遠遠小於沒有快取時產生的流量。所以在估算頻寬的時候,我們還得考慮攜帶快取瀏覽的瀏覽者在總瀏覽者中所佔的比例,說白了就是回頭客的比例,這樣才能作出準確的判斷,否則會多花很多冤枉錢。

參考資料:caching tutorial for web authors and webmasters(英文版)(中文版)

web快取技術

php本身沒有所謂處理快取的函式,因為快取實現的方式很多種.如檔案快取,那麼就是操作檔案的相關函式,如memcached,php也有相關的擴充套件函式支援.快取如何使用取決於你的程式快取方式和內容 ob 系列函式是處理向瀏覽器傳送資料的快取,跟資料快取是兩碼事 如果你不使用ob start 那麼你輸...

web快取技術

web快取包括瀏覽器快取,資料庫快取,伺服器快取。反向 伺服器,在資料 過程中,可以快取一些資料,以提高響應速度。這個了解的不多,不多寫了。我們可以將一些讀取非常頻繁的資料,比如訪問次數,表單中顯示的資料等,儲存在redis,memcached等基於記憶體的nosql資料庫中,作為快取,提高響應速度...

小表快取到記憶體簡析

小表快取到記憶體簡析 oracle的db buffer pool由三部分組成 buffer pool defualt buffer pool keep buffer pool recycle 如果要把表釘死在記憶體中,也就是把表釘在keep區。表如果快取的話是快取在keep區 sql alter t...