用於快取的新HTTP標準:Cache-Status和Target-Cache-Control

banq發表於2021-10-22

網際網路工程任務組 (IETF) 的 HTTP 工作組最近釋出了兩個新的 HTTP 標頭草案標準,目標是除錯快取更容易,並提供對快取配置的更多控制。
兩個擬議標準是:

這些旨在更新 HTTP 標準以匹配當今存在的 CDN 支援的網路的現實,建立規範以形式化流行 CDN(如 Fastly、Akamai 和 Cloudflare,所有這些人都參與編寫標準本身)的現有實踐)。
這兩個都是相當新的規範:Cache-Status 已經在 2021 年完成了多輪審查,目前正在等待(自 8 月以來)作為正式 RFC 的最終審查和釋出,而 Targeted Cache-Control Headers 目前是一個採用的標準草案,但是在最後一次徵求反饋意見中。在這兩種情況下,它們都得到了 IETF 的支援,它們已經收到了很多討論,而且在這一點之後它們不太可能會有太大變化。
 

Cache-Status 將如何提供幫助?
網際網路上快取明顯的問題之一是多個快取/CDN系統之間的可追溯性。對於給定的響應,它到底來自哪裡,經過多少CDN?
這個響應是來自快取還是來自真實伺服器?如果它來自快取,是哪個快取?它會繼續這樣做多久?如果它不是來自快取,為什麼不呢?是否儲存了此新響應以供以後使用?

Cache-Status響應報頭提供了一種系列快取資訊的結構,所有快取資訊被包含在其中都是以一致的格式的提供,這些資訊包括響應內容本身,所有CDN或其他能看見該請求的快取資訊。
格式:

Cache-Status: CacheName; param; param=value; param..., CacheName2; param; param...


如下是一個例項:
Cache-Status: OriginCache; hit; ttl=1100, "CDN Company Here"; fwd=uri-miss;


它是一系列快取,每個快取都有零個或多個狀態引數。快取按響應順序排列:第一個快取是最靠近源伺服器的快取,最後一個快取是最靠近客戶端的快取。
值得注意的是,響應可能會與此標頭一起儲存在快取中,並且會保留在未來的響應中。儘管如此,還是可以使用從右側讀取的引數來了解這次響應具體儲存在哪裡,以及它之前來自哪裡。
此處的帶引數快取值用逗號分隔,而引數本身用分號分隔(這是現在標準化的結構化標頭 RFC 中的sf-listandsf-item語法),當快取名稱包含其他無效時,可以引用它們空格等字元。
引數定義:
  • hit - 響應來自此快取,而沒有向上遊傳送請求
  • fwd=<reason>- 如果設定,請求被向上傳送到下一層。這是有原因的:
    • fwd=bypass - 快取配置為不處理此請求
    • fwd=method - 由於使用的 HTTP 方法,必須轉發請求
    • fwd=uri-miss - 請求 URI 沒有可用的匹配快取資料
    • fwd=vary-miss- URI 有匹配的快取資料,但Vary標頭中列出的標頭不匹配
    • fwd=miss - 沒有匹配的快取資料可用(出於其他原因,例如,如果快取不確定原因)
    • fwd=stale - 有匹配的快取資料,但它是陳舊的
    • fwd=partial- 存在匹配的快取資料,但僅針對部分響應(例如,先前的請求使用了Range標頭)
    • fwd=request - 請求請求的非快取資料(例如在其 Cache-Control 標頭中)
  • fwd-status=<status>- 如果fwd設定,這是從下一跳收到的響應狀態
  • stored- 如果fwd已設定,則表示接收到的響應是否由此快取儲存以備後用
  • collapsed- 如果fwd設定了,這表示請求是否被另一個請求摺疊(即不重複,因為等效的請求已經在處理中)
  • ttl=<ttl> - 此快取將將此響應視為“新鮮”的時間(以秒為單位)多長時間
  • key - 此快取中響應的(特定於實現的)鍵
  • detail - 一個額外的自由格式欄位,用於附加特定於實現的資訊

使用這些,我們可以解釋響應頭,如:

Cache-Status: ExampleCache; hit; ttl=30; key=/abc


這意味著 ExampleCache 收到了請求,它在其快取中(在key/abc 下)找到了一個響應並將其返回,並希望在接下來的 30 秒內繼續這樣。

....
  

Targeted Cache-Control
現有的Cache-Control 標頭是在更簡單的時間(1999 年)設計的。今天響應的 Cache-Control 定義了一個指令列表,這些指令告訴快取如何處理響應,如下所示:
 

Cache-Control: max-age=600, stale-while-revalidate=300, private


這意味著“將此內容快取 10 分鐘,然後在您嘗試重新驗證它時再提供最多 5 分鐘的舊內容,但只能在私人(單使用者,例如瀏覽器)快取中執行此操作”。
這有點生硬——處理請求的所有快取必須以完全相同的方式遵循此處設定的規則。
引入Targeted Cache-Control新標頭可設定僅針對特定快取而非所有快取的快取控制指令來解決此問題。

<Target>-Cache-Control: param, param=value, param...


標頭以應適用的特定目標為字首。該語法在技術上與 Cache-Control 使用的語法略有不同,因為它現在使用標準的結構化欄位格式,但實際上幾乎相同。

Targeted 可能是唯一的服務或元件名稱,或一整類快取。規範僅定義了一個目標 - CDN-Cache-Control,它應該適用於所有分散式 CDN 快取,但不適用於其他快取 - 但可以稍後定義其他類。將來,您可以想象Client-Cache-Control僅為 HTTP 客戶端、ISP-Cache-Control等。
如果您已經熟悉現有的快取機制,那麼這非常簡單且易於使用。目標標頭匹配某些目標,您可以根據需要配置每個目標的快取規則,最佳匹配獲勝。例如:

Client-Cache-Control: must-revalidate
CDN-Cache-Control: max-age=600, stale-after-revalidate=300
Squid-Cache-Control: max-age=60
Cache-Control: no-store


說明如下:
  • 終端客戶端(至少,那些識別出Client-Cache-Control我剛剛製作的標頭的客戶端)可以快取此內容,但每次使用前都必須重新驗證它
  • 所有 CDN 都可以將內容快取 10 分鐘,然後使用過時的響應同時重新驗證它額外的 5 分鐘
  • Squid(快取反向代理)只能快取 60 秒的內容(並且在它過時時隱式不能使用它,因為沒有stale-while-revalidate指令)
  • 任何其他人或任何不理解目標快取控制指令的人都絕對不能快取此內容。

 
新規範本身就在此處的GitHub 上,您可以在該儲存庫中提交問題(或向工作組郵件列表傳送訊息)以分享您的想法。

 

相關文章