HTTP緩存知道這些就夠了

隨着用戶訪問量越來越大,緩存變得越來越重要。HTTP文件緩存可以減少冗餘數據的傳輸;緩解網絡瓶頸;降低對原始服務器的請求;以及降低距離延遲。

命中和未命中

有了緩存,就可以保留第一條服務器響應的副本,後繼請求就可以有緩存的副本來應對了。可以用已有的副本爲某些達到緩存的請求提供服務,這些被稱爲緩存命中(cache hit)。HTTP沒有爲用戶提供一種手段來區分響應是否緩存命中的,還是訪問原始服務器得到的。在客戶端使用Date首部,將響應中Date首部的值與當前時間進行比較,如果響應中的日期值比較早,客戶端通常就可以認爲是一條緩存的響應。現代瀏覽器通常會使用200 OK (from disk cache)進行標識來自緩存
緩存fromcache.png

再驗證

原始服務器的內容可能會發生變化,緩存要不時的對其進行檢測,看看它們保存的副本是否仍是服務器上最新的副本,這些“新鮮度檢測”被稱爲HTTP再驗證(revalidation)。

文檔過期

通過特殊的HTTP Cache-Control:max-age首部(HTTP/1.1)和Expires首部(HTTP/1.0+),HTTP讓原始服務器向每個文檔附件一個“過期日期”。在文檔過期之前,緩存可以以任意頻率使用這些副本,而無需與服務器聯繫(不會發起任何請求)。

首部 描述
Cache-Control:max-age max-age值定義了文檔的最大使用期—從第一次生成文檔到文檔不再新鮮、無法使用爲止(單位:秒) Cache-Control:max-age=3600
Expires 指定一個絕對的過期日期 Expires:Fri, 30 Jun 2017 11:40:21 GMT

用條件方法進行再驗證

HTTP的條件方法可以高效地實現再驗證。HTTP允許緩存向原始服務器發送一個“條件Get請求”,請求服務器只有在文檔與緩存中現有的副本不同時,纔回送對象主體;否則值返回304 Not Modified,不攜帶主體。

首部 描述
If-Modified-Since:<date> 如果從指定日期之後文檔被修改過了,就執行請求的方法。可以與Last-Modified服務器響應首部配合使用,只有在內容被修改後與已緩存版本有所不同時纔去獲取內容。
If-None-match:<tags> 服務器可以爲文檔提供特殊的標籤ETag,而不是將其與最近日期相匹配,這些標籤就像序列號一樣。如果已緩存標籤與服務器文檔中的標籤有所不同,就會執行請求的方法。

如果服務器發送了一個實體標籤,HTTP/1.1客戶端就必須使用實體標籤驗證器。如果服務器只回送了一個Last-Modified值,客戶端就可以使用If-Modified-Since驗證。如果都提供了,HTTP/1.0和HTTP/1.1緩存都可以正確響應。

緩存的處理步驟

(1)接收—緩存從網絡中讀取抵達的請求報文;
(2)解析—緩存對報文進行解析,提取出URL和各種首部;
(3)查詢—緩存查看是否已有本地副本可用,如果沒有,就獲取一份副本(並將其保存在本地);
(4)新鮮度檢測—緩存查看已緩存副本是否足夠新鮮,如果不是,就詢問服務器是否有任何更新條件Get請求
(5)創建響應—緩存會用新的首部和已緩存的主體來構建一條響應報文;
(6)發送—緩存通過網絡將響應發回給客戶端;
(7)日誌—緩存可選地創建一個日誌文件條目來描述這個事物。
HTTP文件緩存判斷機制流程

  1. Cache-Control:相對時間(秒爲單位)(或者,Expires:絕對時間)如果未過期,直接讀取瀏覽器緩存文件,不發生任何HTTP請求。
  2. 在瀏覽器端判斷上次返回頭中是否包含Etag信息,有則連同If-None-Match一起向服務器端發送條件Get請求,304說明未做過修改,如果是200需要進入下一步;
  3. 在瀏覽器端判斷上次返回頭中是否包含Last-Modify信息,有則連同If-Modified-Since一起向服務器端發送條件Get請求,內容失效返回200,否則304;
  4. 如果Etag和Last-Modify都不存在,直接向服務器請求。

**注意:**如果返回304,不會有內容,節省請求大小!

控制緩存的能力

服務器可以通過HTTP定義的幾種方式來指定在文檔過期之前可以將其緩存多長時間。按照優先級遞減的順序:

  • 附件一個Cache-Control: no-store首部到響應中去;
  • 附件一個Cache-Control: no-cache首部到響應中去;
  • 附件一個Cache-Control: must-revalidate首部到響應中去;
  • 附件一個Cache-Control: max-age首部到響應中去;
  • 附加一個Expires日期首部到響應中去;
  • 不附加過期信息,讓緩存確定自己的過期日期。

**注意:**標識爲no-store的響應會禁止緩存對響應進行復制。緩存通常會像非緩存代理服務器一樣,向客戶端轉發一條no-store響應,熱後刪除對象;標識爲no-cache的響應實際上是可以存儲在本地緩存區中的,只是在與原始服務器進行新鮮度再驗證之前,緩存不能將其提供給客戶端使用。

客戶端的新鮮度限制

Web瀏覽器都有Refresh(刷新)或Reload(重載)按鈕,可以強制對瀏覽器或代理緩存中可能過期的內容進行刷新。Refresh按鈕會發佈一個附加了Cache-Control請求首部的Get請求,這個請求會強制進行再驗證,或者無條件地從服務器獲取文檔。

Safari/Firefox瀏覽器下通過Cache-Control:max-age=0進行控制;Chrome瀏覽器勾選Disable cache下通過Cache-Control:no-cache Pragma:no-cache
disableCache

注意:HTML2.0定義了<META HTTP-EQUIV="Cache-control" CONTENT="no-cache">來標記非緩存,其並不是控制文檔緩存特性的最好方法。

緩存和廣告

廣告通常是向用戶顯示一次廣告內容,內容提供商就會得到相應的收益。緩存—它們會向原始服務器隱藏實際的訪問次數。現在廣告商會使用各種類型的“緩存清除”技術來確保緩存不會竊取他們的命中流量。**常用解決方案:**每次訪問都與原始服務器進行再驗證(攜帶no-cache或每次訪問重寫廣告URL)。這樣,每次訪問都會將命中推向原始服務器,但通常不會傳送任何主題數據,不會降低失誤處理速度。

緩存層次結構

其基本思想是在靠近客戶端的地方使用小型廉價緩存,而更高層次中,則逐步採用更大、功能更強的緩存來裝載多用戶共享的文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章