《HTTP權威指南》--HTTP緩存機制及原理

本文整理自《HTTP權威指南》、《圖解HTTP 》。瀏覽器

寫在前面

本身想了解HTTP緩存時,看了許多相關文章,發現大多從強緩存和協商緩存分類介紹,仔細研究卻發現文章描述總有些自我矛盾。緩存

因而想從參考文獻學習,然而查閱《HTTP權威指南》、《圖解HTTP》以及一些文檔後,無一提到「強緩存」和「協商緩存」,更加困惑。但願看到這篇文章且瞭解這兩個定義出處的同窗不吝賜教。服務器

因此決定拋棄許多熱門文章描述的「強緩存」、「協商緩存」,從《HTTP權威指南》、《圖解HTTP》學習,畢竟HTTP緩存就是那麼個事,敘述清楚就好。網絡

因而有了這篇文章。性能

緩存的基礎知識

緩存是什麼

緩存是指代理服務器或客戶端本地磁盤內保存的資源副本學習

緩存保存在哪

  • 代理服務器中
  • 客戶端瀏覽器中

緩存能夠保存在緩存服務器中,也能夠存在客戶端瀏覽器中。代理

緩存服務器是代理服務器的一種,並歸類在緩存代理類型中。本篇文章下面將詳細描述緩存服務器的緩存。code

爲何須要緩存

利用緩存可減小對原始服務器的訪問,所以就節省了通訊流量和通訊時間。cdn

緩存有如下優勢:server

  • 減小了冗餘的數據傳輸
  • 緩解了網絡瓶頸問題
  • 下降了對原始服務器的要求
  • 下降了距離時延

緩存命中和未命中

因爲緩存沒法保存世界上每份文檔的副本(巨大而且沒法及時更新),就出現了緩存的命中與未命中狀況。

  • 緩存命中(cache hit):到達緩存的請求能夠由已有的副本提供服務。
  • 緩存未命中(cache miss):到達緩存的請求因爲沒有副本可用,而被轉發給原始服務器。

新鮮度

就算緩存保存了副本,可能不是全部的已緩存副本都與服務器上的文檔一致。畢竟,這些文檔會隨着時間發生變化。若是緩存提供的老是老的數據,就會變得毫無用處。

HTTP有一些簡單的機制保持已緩存數據與服務器數據之間充分一致。HTTP將這些簡單的機制稱爲文檔過時(document expiration)和服務器再驗證(server revalidation)。

再驗證

原始服務器的內容可能會發生變化,緩存對其進行檢測,看它們保存的副本是否還是服務器上最新的副本。這些「新鮮度檢測」成爲HTTP再驗證。

爲了有效的進行再驗證,HTTP定義了一些特殊的請求,不用從服務器上獲取整個對象,就能夠快速檢測出內容是不是最新的。後面會解釋HTTP的新鮮度檢測規則。

緩存的過程

HTTP緩存流程圖以下,顯示緩存處理器如何處理請求。

HTTP緩存流程圖

接收每個緩存請求,緩存處理器對請求解析後,首先要查看是否命中,便是否有本地副本可用:

  • 若是沒有,就從服務器獲取一份副本(並將其保存在本地)。

  • 若是有,就要查看已緩存副本是否足夠新鮮

    • 若是新鮮,緩存用新首部和已緩存的主題構建一條響應報文,提供給客戶端
    • 若是不新鮮,就與服務器進行再驗證,詢問服務器是否有任何更新:
      • 再驗證命中:即服務器對象未被修改,服務器向客戶端發送一個小的HTTP 304 Not Modified 響應(包含一個新的過時時間)
      • 再驗證未命中:即服務器對象與已緩存副本不一樣,服務器向客戶端發送一條普通的、帶有完整內容的HTTP 200 OK響應(新首部+新主體)。
      • 對象唄刪除:若是服務器對象已經被刪除了,服務器就回送一個404 Not Found響應,緩存也會將其副本刪除。

新鮮度檢測規則

經過HTTP Cache-ControlExpires 首部,HTTP讓原始服務器向每一個文檔附加了一個「過時日期」,這些首部說明了在多長時間內能夠將這些內容視爲新鮮的。

在緩存文檔過時以前,緩存能夠以任意頻率使用這些副本,而無需與服務器聯繫----固然,除非客戶端請求中包含阻止提供已緩存或未驗證資源的首部。但一旦已緩存文檔國企,緩存就必須與服務器進行覈對,詢問文檔是否被修改過,若是被修改過,就喲啊獲取一份新鮮(帶有新的過時日期)的副本。

過時日期和使用期

Expires首部

Expires是HTTP/1.0+,指定一個絕對的過時日期。若是過時日期已通過了,就說明文檔再也不新鮮了。 例如:

Cache-Control: max-age

Cache-Control: max-age是HTTP/1.1,是相對時間,來指定過時日期,定義了文檔的最大使用期,以秒爲單位。例如:

Cache-Control的優先級大於Expires

服務器再驗證

僅僅是已緩存文檔過時了並不意味着它和原始服務器上的文檔有實際的區別;只意味着要到了進行覈對的時間了。這種狀況被稱爲「服務器再驗證」。

對緩存再驗證來講最有用的2個首部是If-Modified-SinceIf-None-Match

If-Modified-Since:Date再驗證

If-Modified-Since一般被稱爲IMS請求,只有與自某個日期以後資源發生了變化的時候,IMS請求才會指示服務器執行請求。

Last-Modified服務器響應首部配合使用,此首部使用絕對時間表示最後修改日期。都是絕對時間。

If-None-Match:實體標籤(ETag)再驗證

有些狀況下僅使用最後修改日期進行驗證是不夠的,HTTP容許用戶對實體標籤(ETag)的「版本標識符」進行比較。

ETag是附加到文檔上的任意標籤(引用字符串)。當發佈者對文檔進行修改時,能夠修改ETag來講明這個新的版本。

使用優先級

ETag優先級大於Last-Modified

  • 只要服務器回送了一個實體標籤,HTTP/1.1 客戶端就必須使用實體標籤驗證器。

  • 只有當服務器只回送了一個Last-Modified值,客戶端可使用If-Modified-Since

  • 若是服務器兩個都提供了,客戶端要使用兩種驗證方案,而且只有兩個都知足時才能返回304。

控制緩存的能力

服務器能夠經過HTTP定義的幾種方式來指定文檔過時以前能夠將其緩存多長時間。按照優先級遞減,服務器能夠:

  • 附加一個Cache-Control: no-store首部到響應中去;
  • 附加一個Cache-Control: no-cache首部到響應中去;
  • 附加一個Cache-Control: must-revalidate首部到響應中去;
  • 附加一個Cache-Control: max-age首部到響應中去;

Cache-Control: no-store首部

禁止緩存對響應進行復制。緩存應該儘快從存儲器中刪除文檔的全部痕跡。

Cache-Control: no-cache首部

除非資源進行了再驗證,不然這個客戶端不會接受已緩存的資源。

Cache-Control: must-revalidate首部

能夠配置緩存,使其提供一些陳舊的對象,以提供性能。

Cache-Control: max-age首部

若是將最大使用期設置爲0,則服務器能夠請求緩存不要緩存文檔,從而每次訪問的時候都進行刷新。

還有一個s-maxage首部與max-age類似,但僅適用於公有緩存。

相關文章
相關標籤/搜索