天天看點

《HttpClient官方文檔》第六章 HTTP 緩存

httpclient cache 提供了用httpclient(等效浏覽器緩存的java實作)來相容http / 1.1的緩存層。實作遵循責任鍊模式,httpclient緩存的實作類可以替代預設無緩存的httpclient;完全可以通過緩存實作的請求将不會觸發實際的原始請求。在可以的情況下,使用gets條件if-modified-since和/or if-none-match請求頭,會自動驗證舊的緩存項。http / 1.1緩存一般被設計成語義透明的,也就是說,緩存不會改變用戶端和伺服器端的請求響應之間交換的意義。是以,向一個現有的用戶端-伺服器的關系中添加httpclient是安全的。盡管從一個http協定的角度來看,緩存子產品是用戶端的一部分,實作的目标是滿足基于透明緩存代理的要求。最後,緩存httpclient包括支援rfc 5861(stale-if-error和stale-while-revalidate)指定的cache – control擴充。 當緩存httpclient執行一個請求時,它會通過以下流程:

檢查要求是否符合基本的http 1.1協定并嘗試正确的請求。

重新整理目前請求導緻無效的一些緩存項。

确定目前請求可以從緩存中提供。如果不能, 則直接将這個請求發送給原始伺服器并換回響應,如果合适的話儲存緩存.

如果是cache-servable請求時,将嘗試從緩存中讀取。當緩存中沒有的情況下,調用原始的伺服器,如果可以的話将響應緩存。

如果緩存中的響應能夠被當做一個響應提供服務,構造一個包含bytearrayentity的basichttpresponse并傳回。否則,嘗試重新驗證對原始伺服器的緩存項.

當一個緩存的響應不能重新生效的情況下,調用原始伺服器,如果可以的話緩存響應.

當緩存httpclient收到響應時,它通過以下流程:

根據協定内容,檢查響應。

确定響應是否可以被緩存。

如果可以被緩存,讀取配置中允許的最多内容,并将其儲存在緩存中。

如果對緩存來說響應過大,則重新建構被消費的部分響應,并跳過緩存流程直接傳回。

需要着重注意的是,httpclient cache本身并不是一個httpclient的不同實作,而是通過插件的方式作為一個額外管道執行請求。

我們相信httpclient緩存是無條件地符合rfc-2616。也就是說無論規範表明對于http緩存 必須、不必須、可以、不可以,緩存層都會試圖以滿足這些條件的方式實作。 這就意味着,當你使用緩存子產品時,不會發生錯誤的行為。

下面是一個如何建立一個基本的緩存httpclient例子。根據配置,他會存儲一個最大數量為1000的緩存執行個體,每個最多能夠儲存8192 bytes。這裡的數字僅僅是個例子,并不是規定,也不能被看做成建議。

httpclient cache 繼承了所有非緩存實作的配置項和參數(包括像逾時時間、連接配接池大小這樣的設定選項)。對于緩存的具體配置,可以根據以下幾個方提供一個緩存配置執行個體指定行為:

緩存大小,後端存儲支援這些限制,可以像最大的可緩存響應體大小一樣指定緩存項的數量.

公共/私有緩存. 在預設情況下,緩存子產品本身是一個共享緩存,例如,不會緩存帶有授權請求頭的響應和标記為”cache-control: private”的響應。然而,如果緩存僅僅被應用于一個“使用者”(類似于浏覽器緩存的行為)邏輯,那麼它将關閉共享緩存設定。

啟發式緩存. 按照rfc2616, 緩存可以緩存特定的緩存條目,即使沒有顯示原始設定的緩存控制頭。這種行為在預設情況下是關閉的,但是如果你處理的是一個沒有完全設定原始請求頭的請求,你可能想要打開它。你需要一個可以啟發式的緩存,然後指定一個預設的新生命周期,并且/或者資源被最後修改後的一小段時間。參考http/1.1 rfc的13.2.2和13.2.4部分,可以獲得啟發式緩存的更多細節。

背景驗證. 緩存子產品支援rfc5861的stale-while-revalidate指令,允許背景特定的緩存項重新生效。可以需要調整設定背景工作線程的最小和最大工作數量,以及他們回收前閑置的最大時間。沒有足夠的worker來跟上需求時,您還可以控制隊列的大小用于重新生效線程。

預設的httpclient cache的實作會存儲緩存項,并且在應用的jvm記憶體中緩存響應體。雖然這些能夠提供高性能,但是有記憶體大小的限制,或者因為緩存項在應用重新開機後會失效,是以可能并不适用于您的應用。目前版本允許将緩存項儲存到硬碟上,或者使用其他外部程序ehcache和memcached存儲緩存項。如果這些選項滿足不了你的應用,可以通過實作httpcachedstorage提供你自己的背景存儲,并且在建構的時候提供給緩存httpclient。在這種情況下,緩存項會通過你自己的架構存儲,但是會重用所有http/1.1協定的邏輯和緩存處理。一般來說,應該能夠建立一個支援原子操作的key/value存儲(類似于java的map接口)的httpcachedstorage實作。最後,通過一些額外的努力完全有可能建立一個多層緩存層次結構; 比如,包裝一個記憶體中的緩存httpclient在磁盤上的存儲緩存條目,在memcached中遠端存儲,後一種模式類似于虛拟記憶體,l1 / l2處理器緩存等。