Web緩存基礎:術語、HTTP報頭和緩存策略

簡介

對于您的站點的訪問者來說,智能化的內容緩存是提高用戶體驗最有效的方式之一。緩存,或者對之前的請求的臨時存儲,是HTTP協議實現中最核心的內容分發策略之一。分發路徑中的組件均可以緩存內容來加速后續的請求,這受控于對該內容所聲明的緩存策略。

在這份指南中,我們將討論一些Web內容緩存的基本概念。這主要包括如何選擇緩存策略以保證互聯網范圍內的緩存能夠正確的處理您的內容。我們將談一談緩存帶來的好處、副作用以及不同的策略能帶來的性能和靈活性的最大結合。

什么是緩存(caching)?

緩存(caching)是一個描述存儲可重用資源以便加快后續請求的行為的術語。有許多不同類型的緩存,每種都有其自身的特點,應用程序緩存和內存緩存由于其對特定回復的加速,都很常用。

這份指南的主要講述的Web緩存是一種不同類型的緩存。Web緩存是HTTP協議的一個核心特性,它能最小化網絡流量,并且提升用戶所感知的整個系統響應速度。內容從服務器到瀏覽器的傳輸過程中,每個層面都可以找到緩存的身影。

Web緩存根據特定的規則緩存相應HTTP請求的響應。對于緩存內容的后續請求便可以直接由緩存滿足而不是重新發送請求到Web服務器。

好處

有效的緩存技術不僅可以幫助用戶,還可以幫助內容的提供者。緩存對內容分發帶來的好處有:

  • 減少網絡開銷:內容可以在從內容提供者到內容消費者網絡路徑之間的許多不同的地方被緩存。當內容在距離內容消費者更近的地方被緩存時,由于緩存的存在,請求將不會消耗額外的網絡資源。
  • 加快響應速度:由于并不是必須通過整個網絡往返,緩存可以使內容的獲得變得更快。緩存放在距用戶更近的地方,例如瀏覽器緩存,使得內容的獲取幾乎是瞬時的。
  • 在同樣的硬件上提高速度:對于保存原始內容的服務器來說,更多的性能可以通過允許激進的緩存策略從硬件上壓榨出來。內容擁有者們可以利用分發路徑上某個強大的服務器來應對特定內容負載的沖擊。
  • 網絡中斷時內容依舊可用:使用某種策略,緩存可以保證在原始服務器變得不可用時,相應的內容對用戶依舊可用。

術語

在面對緩存時,您可能對一些經常遇到的術語可能不太熟悉。一些常見的術語如下:

  • 原始服務器:原始服務器是內容的原始存放地點。如果您是Web服務器管理員,它就是您所管理的機器。它負責為任何不能從緩存中得到的內容進行回復,并且負責設置所有內容的緩存策略。
  • 緩存命中率:一個緩存的有效性依照緩存的命中率進行度量。它是可以從緩存中得到數據的請求數與所有請求數的比率。緩存命中率高意味著有很高比例的數據可以從緩存中獲得。這通常是大多數管理員想要的結果。
  • 新鮮度:新鮮度用來描述一個緩存中的項目是否依舊適合返回給客戶端。緩存中的內容只有在由緩存策略指定的新鮮期內才會被返回。
  • 過期內容:緩存中根據緩存策略的新鮮期設置已過期的內容。過期的內容被標記為“陳舊”。通常,過期內容不能用于回復客戶端的請求。必須重新從原始服務器請求新的內容或者至少驗證緩存的內容是否仍然準確。
  • 校驗:緩存中的過期內容可以驗證是否有效以便刷新過期時間。驗證過程包括聯系原始服務器以檢查緩存的數據是否依舊代表了最近的版本。
  • 失效:失效是依據過期日期從緩存中移除內容的過程。當內容在原始服務器上已被改變時就必須這樣做,緩存中過期的內容會導致客戶端發生問題。

還有許多其他的緩存術語,不過上面的這些應該能幫助您開始。

什么能被緩存?

某些特定的內容比其他內容更容易被緩存。對大多數站點來說,一些適合緩存的內容如下:

  • Logo和商標圖像
  • 普通的不變化的圖像(例如,導航圖標)
  • CSS樣式表
  • 普通的Javascript文件
  • 可下載的內容
  • 媒體文件

這些文件更傾向于不經常改變,所以長時間的對它們進行緩存能獲得好處。

一些項目在緩存中必須加以注意:

  • HTML頁面
  • 會替換改變的圖像
  • 經常修改的Javascript和CSS文件
  • 需要有認證后的cookies才能訪問的內容

一些內容從來不應該被緩存:

  • 與敏感信息相關的資源(銀行數據,等)
  • 用戶相關且經常更改的數據

除上面的通用規則外,通常您需要指定一些規則以便于更好地緩存不同種類的內容。例如,如果登錄的用戶都看到的是同樣的網站視圖,就應該在任何地方緩存這個頁面。如果登錄的用戶會在一段時間內看到站點中用戶特定的視圖,您應該讓用戶的瀏覽器緩存該數據而不應讓任何中介節點緩存該視圖。

Web內容緩存的位置

Web內容會在整個分發路徑中的許多不同的位置被緩存:

  • 瀏覽器緩存:Web瀏覽器自身會維護一個小型緩存。典型地,瀏覽器使用一種策略指示緩存最重要的內容。這可能是用戶相關的內容或可能會再次請求且下載代價較高。
  • 中間緩存代理:任何在客戶端和您的基礎架構之間的服務器都可以按期望緩存一些內容。這些緩存可能由ISP(網絡服務提供者)或者其他獨立組織提供。
  • 反向緩存:您的服務器基礎架構可以為后端的服務實現自己的緩存。如果實現了緩存,那么便可以在處理請求的位置返回相應的內容而不用每次請求都使用后端服務。

上面的這些位置通常都可以根據它們自身的緩存策略和內容源的緩存策略緩存一些相應的內容。

緩存頭部

緩存策略依賴于兩個不同的因素。所緩存的實體本身需要決定是否應該緩存可接受的內容。它可以只緩存部分可以緩存的內容,但不能緩存超過限制的內容。

緩存行為主要由緩存策略決定,而緩存策略由內容擁有者設置。這些策略主要通過特定的HTTP頭部來清晰地表達。

經過幾個不同HTTP協議的變化,出現了一些不同的針對緩存方面的頭部,它們的復雜度各不相同。下面列出了那些你也許應該注意的:

  • Expires:盡管使用范圍相當有限,但Expires頭部是非常簡潔明了的。通常它設置一個未來的時間,內容會在此時間過期。這時,任何對同樣內容的請求都應該回到原始服務器處。這個頭部或許僅僅最適合回退模式(fall back)。
  • Cache-Control:這是Expires的一個更加現代化的替換物。它已被很好的支持,且擁有更加靈活的實現。在大多數案例中,它比Expires更好,但同時設置兩者的值也無妨。稍后我們將討論您可以設置的Cache-Control的詳細選項。
  • ETagETag用于緩存驗證。源服務器可以在首次服務一個內容時為該內容提供一個獨特的ETag。當一個緩存需要驗證這個內容是否即將過期,他會將相應的ETag發送回服務器。源服務器或者告訴緩存內容是一致的,或者發送更新后的內容(帶著新的ETag)。
  • Last-Modified:這個頭部指明了相應的內容最后一次被修改的時間。它可能會作為保證內容新鮮度的驗證策略的一部分被使用。
  • Content-Length:盡管并沒有在緩存中明確涉及,Content-Length頭部在設置緩存策略時很重要。某些軟件如果不提前獲知內容的大小以留出足夠空間,則會拒絕緩存該內容。
  • Vary:緩存系統通常使用請求的主機和路徑作為存儲該資源的鍵。當判斷一個請求是否是請求同樣內容時,Vary頭部可以被用來提醒緩存系統需要注意另一個附加頭部。它通常被用來告訴緩存系統同樣注意Accept-Encoding頭部,以便緩存系統能夠區分壓縮和未壓縮的內容。

Vary頭部的隱語

Vary頭部提供給您存儲同一個內容的不同版本的能力,代價是降低了緩存的容量。

在使用Accept-Encoding時,設置Vary頭部允許明確區分壓縮和未壓縮的內容。這在服務某些不能處理壓縮數據的瀏覽器時很重要,它可以保證基本的可用性。Vary的一個典型的值是Accept-Encoding,它只有兩到三個可選的值。

一開始看上去User-Agent這樣的頭部可以用于區分移動瀏覽器和桌面瀏覽器,以便您的站點提供差異化的服務。但User-Agent字符串是非標準的,結果將會造成在中間緩存中保存同一內容的許多不同版本的緩存,這會導致緩存命中率的降低。Vary頭部應該謹慎使用,尤其是您不具備在您控制的中間緩存中使請求標準化的能力(也許可以,比如您可以控制CDN的話)。

緩存控制標志怎樣影響緩存

上面我們提到了Cache-Control頭部如何被用與現代緩存策略標準。能夠通過這個頭部設定許多不同的緩存指令,多個不同的指令通過逗號分隔。

一些您可以使用的指示內容緩存策略的Cache-Control的選項如下:

  • no-cache:這個指令指示所有緩存的內容在新的請求到達時必須先重新驗證,再發送給客戶端。這條指令實際將內容立刻標記為過期的,但允許通過驗證手段重新驗證以避免重新下載整個內容。
  • no-store:這條指令指示緩存的內容不能以任何方式被緩存。它適合在回復敏感信息時設置。
  • public:它將內容標記為公有的,這意味著它能被瀏覽器和其他任何中間節點緩存。通常,對于使用了HTTP驗證的請求,其回復被默認標記為privatepublic標記將會覆蓋這個設置。
  • private:它將內容標記為私有的。私有數據可以被用戶的瀏覽器緩存,但不能被任何中間節點緩存。它通常用于用戶相關的數據。
  • max-age:這個設置指示了緩存內容的最大生存期,它在最大生存期后必須在源服務器處被驗證或被重新下載。在現代瀏覽器中這個選項大體上取代了Expires頭部,瀏覽器也將其作為決定內容的新鮮度的基礎。這個選項的值以秒為單位表示,最大可以表示一年的新鮮期(31536000秒)。
  • s-maxage:這個選項非常類似于max-age,它指明了內容能夠被緩存的時間。區別是這個選項只在中間節點的緩存中有效。結合這兩個選項可以構建更加靈活的緩存策略。
  • must-revalidate:它指明了由max-ages-maxageExpires頭部指明的新鮮度信息必須被嚴格的遵守。它避免了緩存的數據在網絡中斷等類似的場景中被使用。
  • proxy-revalidate:它和上面的選項有著一樣的作用,但只應用于中間的代理節點。在這種情況下,用戶的瀏覽器可以在網絡中斷時使用過期內容,但中間緩存內容不能用于此目的。
  • no-transform:這個選項告訴緩存在任何情況下都不能因為性能的原因修改接收到的內容。這意味著,緩存不允許壓縮接收到的內容(沒有從原始服務器處接收過壓縮版本的該內容)并發送。

這些選項能夠以不同的方式結合以獲得不同的緩存行為。一些互斥的值如下:

  • no-cacheno-store以及由其他前面未提到的選項指明的常用的緩存行為
  • publicprivate

如果no-storeno-cache都被設置,那么no-store會取代no-cache。對于非授權的請求的回復,public是隱含的設置。對于授權的請求的回復,private選項是隱含的。他們可以通過在Cache-Control頭部中指明相應的相反的選項以覆蓋。

開發一種緩存策略

在理想情況下,任何內容都可以被盡可能緩存,而您的服務器只需要偶爾的提供一些驗證內容即可。但這在現實中很少發生,因此您應該嘗試設置一些明智的緩存策略,以在長期緩存和站點改變的需求間達到平衡。

常見問題

在許多情況中,由于內容被產生的方式(如根據每個用戶動態的產生)或者內容的特性(例如銀行的敏感數據),這些內容不應該被緩存。另一些許多管理員在設置緩存時可能面對的問題是外部緩存的數據未過期,但新版本的數據已經產生。

這些都是經常遇到的問題,它們會影響緩存的性能和您提供的數據的準確性。然而,我們可以通過開發提前預見這些問題的緩存策略來緩解這些問題。

一般性建議

盡管您的實際情況會指導您選擇的緩存策略,但是下面的建議能幫助您獲得一些合理的決定。

在您擔心使用哪一個特定的頭部之前,有一些特定的步驟可以幫助您提高您的緩存命中率。一些建議如下:

  • 為圖像、CSS和共享的內容建立特定的文件夾:將內容放到特定的文件夾內使得您可以方便的從您的站點中的任何頁面引用這些內容。
  • 使用同樣的URL來表示同樣的內容:由于緩存使用內容請求中的主機名和路徑作為鍵,因此應保證您的所有頁面中的該內容的引用方式相同,前一個建議能讓這點更加容易做到。
  • 盡可能使用CSS圖像拼接:對于像圖標和導航等內容,使用CSS圖像拼接能夠減少渲染您頁面所需要的請求往返,并且允許對拼接緩存很長一段時間。
  • 盡可能將主機腳本和外部資源本地化:如果您使用Javascript腳本和其他外部資源,如果上游沒有提供合適的緩存頭部,那么您應考慮將這些內容放在您自己的服務器上。您應該注意上游的任何更新,以便更新本地的拷貝。
  • 對緩存內容收集文件摘要:靜態的內容比如CSS和Javascript文件等通常比較適合收集文件摘要。這意味著為文件名增加一個獨特的標志符(通常是這個文件的哈希值)可以在文件修改后繞開緩存保證新的內容被重新獲取。有很多工具可以幫助您創建文件摘要并且修改HTML文檔中的引用。

對于不同的文件正確地選擇不同的頭部這件事,下面的內容可以作為一般性的參考:

  • 允許所有的緩存存儲一般內容:靜態內容以及非用戶相關的內容應該在分發鏈的所有節點被緩存。這使得中間節點可以將該內容回復給多個用戶。
  • 允許瀏覽器緩存用戶相關的內容:對于每個用戶的數據,通常在用戶自己的瀏覽器中緩存是可以被接受且有益的。緩存在用戶自身的瀏覽器能夠使得用戶在接下來的瀏覽中能夠瞬時讀取,但這些內容不適合在任何中間代理節點緩存。
  • 將時間敏感的內容作為特例:如果您的數據是時間敏感的,那么相對上面兩條參考,應該將這些數據作為特例,以保證過期的數據不會在關鍵的情況下被使用。例如,您的站點有一個購物車,它應該立刻反應購物車里面的物品。依據內容的特點,可以在Cache-Control頭部中使用no-cacheno-store選項。
  • 總是提供驗證器:驗證器使得過期的內容可以無需重新下載而得到刷新。設置ETagLast-Modified頭部將允許緩存向原始服務器驗證內容,并在內容未修改時刷新該內容新鮮度以減少負載。
  • 對于支持的內容設置長的新鮮期:為了更加有效的利用緩存,一些作為支持性的內容應該被設置較長的新鮮期。這通常比較適合圖像和CSS等由用戶請求用來渲染HTML頁面的內容。和文件摘要一起,設置延長的新鮮期將允許緩存長時間的存儲這些資源。如果資源發生改變,修改的文件摘要將會使緩存的數據無效并觸發對新的內容的下載。那時,新的支持的內容會繼續被緩存。
  • 對父內容設置短的新鮮期:為了使得前面的模式正常工作,容器類的內容應該相應的設置短的新鮮期,或者設置不全部緩存。這通常是在其他協助內容中使用的HTML頁面。這個HTML頁面將會被頻繁的下載,使得它能快速的響應改變。支持性的內容因此可以被盡量緩存。

關鍵之處便在于達到平衡,一方面可以盡量的進行緩存,另一方面為未來保留當改變發生時從而改變整個內容的機會。您的站點應該同時具有:

  • 盡量緩存的內容
  • 擁有短的新鮮期的緩存內容,可以被重新驗證
  • 完全不被緩存的內容

這樣做的目的便是將內容盡可能的移動到第一個分類(盡量緩存)中的同時,維持可以接受的緩存命中率。

結論

花時間確保您的站點使用了合適的緩存策略將對您的站點產生重要的影響。緩存使得您可以在保證服務同樣內容的同時減少帶寬的使用。您的服務器因此可以靠同樣的硬件處理更多的流量。或許更重要的是,客戶們能在您的網站中獲得更快的體驗,這會使得他們更愿意頻繁的訪問您的站點。盡管有效的Web緩存并不是銀彈,但設置合適的緩存策略會使您以最小的代價獲得可觀的收獲。


via: https://www.digitalocean.com/community/tutorials/web-caching-basics-terminology-http-headers-and-caching-strategies

作者: Justin Ellingwood
譯者:wwy-hust
校對:wxy
推薦:royaso

本文由 LCTT 原創翻譯,Linux中國 榮譽推出

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容