Web緩存工作原理

現代的商業化代理緩存相當的複雜。這些緩存構建的非常高效,可以支持HTTP和其他一些技術的各種高級特性。但除了一些微妙的細節之外,Web緩存的基本工作原理大多很簡單。對一條HTTP GET報文的基本緩存處理過程包括7個步驟:

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

1. 接收

緩存檢測到一條網絡連接上的活動,讀取輸入數據。高性能的緩存會同時從多條輸入連接上讀取數據,在整條報文抵達之前開始對事務進行處理。

2. 解析

緩存將報文解析爲片段,將首部的各個部分放入易於操作的數據結構中。這樣緩存軟件就更容易處理首部字段並修改他們了。
解析程序還要負責首部各部分的標準化,將大小寫或者可替換數據格式之類不太重要的區別都看成等效的。

3. 查找

緩存獲取URL後,查找本地副本。本地副本可能存儲在內存,本地磁盤,甚至附近的另一臺服務器中。專業級的緩存會使用快速算法來確定本地緩存中是否有某個對象。如果本地沒有這個文檔,他可以根據情形和配置,到原始服務器或父代理中去取,或者返回一條錯誤信息。
已緩存的對象中包含了服務器響應主體和原始服務器響應首部,這樣就會在緩存命中時返回正確的服務器首部。已緩存的對象中還包含一些元數據(metadata),用來記錄對象在緩存中停留了多長時間,以及它被用過多少次等。

4. 新鮮度檢測

HTTP通過緩存將服務器文檔的副本保留一段時間。在這段時間裏,都認爲文檔是”新鮮的”, 緩存可以在不聯繫服務器的情況下,直接提取該文檔。但一旦已緩存副本停留的時間太長,超過了文檔的新鮮度限值(freshness limit),就認爲對象”過時”了,在提供該文檔之前,緩存要再次與服務器進行確認,以查看文檔是否發生了變化。客戶端發送給緩存的所有請求首部自身都可以強制緩存進行再驗證,或者完全避免驗證,這使得事情變得更加的複雜。
HTTP有一組非常複雜的新鮮度檢測規則,緩存產品支持的大量配置選項,以及與非HTTP新鮮度標準進行互通的需要則使得問題變得更加嚴重。
HTTP有一些簡單的機制可以在不要求服務器記住有哪些緩存擁有其文檔副本的情況下,保持已緩存數據與服務器數據之間充分一致。HTTP將這些簡單的機制稱爲文檔過期服務器再認證

4.1 文檔過期(document expiration)

通過特殊的HTTP Cache-Control首部(HTTP/1.0+)和Expires首部(Cache-Control),HTTP讓原始服務器向每個文檔附加了一個”過期時間”。在緩存文件過期之前,緩存可以以任意頻率使用這些副本,而無需與服務器聯繫。

過期響應首部:

首部 描述
Cache-Control: max-age max-age值定義了文檔的最大使用期——從第一次生成文檔
到文檔不再新鮮、無法使用爲止,最大的合法生存時間。
Cache-Control: max-age=484200
Expires 指定一個絕對的過期日期。如果過期日期已經過了,就說明
文檔不再新鮮了
Expires: Fri, 05 Jul 2016, 05:00:00 GMT



由於Cache-Control首部使用的是相對時間而不是絕對時間,所以我們更傾向於使用比較新的Cache-Control首部。絕對時間依賴於計算機時鐘的正確設置。

4.2 服務器再驗證(server recalidation)

僅僅是已緩存文檔過期了並不意味着它與原始服務器上目前處於活躍狀態的文檔有實際的區別,這只是意味着到了要進行覈對的時間了。這種情況被稱爲”服務器再驗證”,說明緩存需要詢問原始服務器文檔是否發生了變化。
HTTP的條件方法可以高效地實現再驗證。HTTP允許緩存向原始服務器一個”條件GET”, 請求服務器只有在文檔和緩存中現有的副本不同時,纔回送對象主體。通過這種方式,將新鮮度檢測和對象獲取結合成了單個條件GET。向GET請求報文中添加一些特殊的條件首部,就可以發起條件GET。

緩存再驗證中使用的兩個條件首部:

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



1. If-Modified-Since: Date 再驗證(IMS請求)

  • 如果自指定日期後,文檔被修改了,IMS條件就爲真,通常GET就會成功執行。攜帶新首部的新文檔會被返回給緩存,新首部除了其他信息之外,還包含了新的過期日期。
  • 如果自指定日期後,文檔沒被修改過,條件就爲假,會像客戶端返回一個小的304 Not Modified響應報文,爲了提高有效性,不會返回文檔的主體。

IMS請求

2. If-None-Match : 實體標籤再認證

有些情況下僅使用最後修改時間進行再驗證是不夠的。爲了解決這些問題,HTTP允許用戶對被稱爲實體標籤(ETag)的”版本標識符”進行比較。實體標籤是附加到文檔上的任意標籤(引用字符串)。它們可能包含了文檔的序列號或版本號,或者是文檔內容的檢驗和及其它指紋信息。
當發佈者對文檔進行修改時,可以修改文檔的實體標籤來說明這個新的版本。這樣,如果實體標籤被修改了,緩存就可以用If-None-Match條件來GET文檔的新副本了。

5. 創建響應

我們希望緩存的響應看起來就像來自原始服務器的一樣,緩存將已緩存的服務器響應首部作爲響應首部的起點。然後緩存對這些基礎首部進行了修改和擴充。
緩存負責對這些首部進行改造,以便與客戶端的要求相匹配。注意,緩存不應該調整Date首部。Date首部表示的是原始服務器最初產生這個對象的時間。

6. 發送

一旦響應首部準備好了,緩存就將響應回送給客戶端。和所有代理服務器一樣,代理緩存要管理與客戶端之間的連接。高性能的緩存會盡全力高效的發送數據,通常可以避免在本地緩存與網絡I/O緩衝區之間進行文檔內容的複製。

7. 日誌

大多數緩存都會保存日誌文件以及與緩存使用的一些統計數據。每個緩存事務結束之後,緩存都會更新緩存命中和未命中數目的統計數據(以及相關的度量值),並將條目插入一個用來顯示請求類型、URL和所發生事件的日誌文件。

8. 緩存處理流程圖

下圖以簡化形式展示了緩存是如何處理請求以獲取一個方法爲GET的URL的。
緩存GET請求的流程圖

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