varnish緩存清除
❶ Cache-Control 的 stale-while-revalidate 指令
在HTTP緩存領域中,stale一詞指的是緩存內容已經過期,如max-age設置的過期時間已屆滿。一旦緩存過期,客戶端需要對緩存執行revalidate操作,獲取最新內容。然而,在特別注重性能的場景下,這種同步更新緩存的方法被認為可能影響性能。
為了解決這個問題,2010年雅虎工程師Mark Nottingham在Cache-Control響應頭中引入了兩個新的擴展指令,其中stale-while-revalidate就是其中之一。此指令的含義是當執行revalidate請求時,客戶端可以不等待,直接使用過期的緩存。一旦revalidate完成,緩存將更新,下次訪問時即可使用最新內容。通俗來講,stale-while-revalidate實現了「後台緩存刷新」或「非同步緩存更新」的功能。
stale-while-revalidate指令的使用類似於max-age,需要指定一個秒數作為參數。例如,Cache-Control: max-age=60, stale-while-revalidate=3600表示在60秒內內容為新鮮狀態,在接下來的3600秒(1小時)內,即使緩存過期,客戶端仍可直接使用過期緩存,並執行非同步revalidate操作。超過3600秒後,緩存完全過期,需要進行同步revalidate。
此指令最初是為了緩存伺服器設計的,因此如Varnish、Squid、Nginx等軟體均支持它。然而,國內CDN廠商是否支持stale-while-revalidate功能尚不確定,因為沒有明確的文檔提及這一點,推測支持率可能不高。而國際CDN廠商中,亞馬遜不支持,Akamai的情況未知,其他一些CDN廠商支持此功能,但整體上是較為小眾的特性。
在瀏覽器端,stale-while-revalidate指令經歷了8年的空白期,直到Chrome在2018年嘗試實現,最終在Chrome 75中默認啟用,並被納入fetch.spec.whatwg.org規范。隨後,Firefox也在上個月實現了此功能。
使用stale-while-revalidate指令時,需要考慮到在指定的時間段內讀取緩存的情況。此時除了能看到直接讀取過期緩存的請求(狀態碼為200),還可以看到非同步刷新緩存的請求(狀態碼為304)。Chrome DevTools可以看到這兩種請求,而Firefox DevTools目前僅能查看直接讀取緩存的請求。
值得注意的是,在stale-while-revalidate指定的時間段結束後,過期的緩存不再被視為過期緩存,而是開啟一個新的生命周期。stale-while-revalidate設定的時間段並不是一定完全經歷,可能會有所偏差。
stale-while-revalidate在CDN上的應用並不廣泛,但在瀏覽器端,它在某些場景下可能有用。例如,當靜態資源的發布是非覆蓋式的,即每次發布新版本都會改變URL中的版本號或哈希值,此時資源的緩存時間會設置得非常長,如一年、三年甚至十年。在這種情況下,stale-while-revalidate通常沒有實際用途,因為它在到期前就已經不再在線上使用。
然而,存在一些場景需要使用stale-while-revalidate,如網站首頁或無法更改URL的情況。例如淘寶首頁是一個可緩存的靜態頁面,或某些需要與第三方共享的URL。在這些情況下,stale-while-revalidate可以發揮作用。
stale-while-revalidate旨在以犧牲內容的新鮮性換取載入速度的提升,但是否使用以及使用多大數值取決於具體場景。通常情況下,傾向於使用max-age較短而stale-while-revalidate較長的策略。甚至在極端情況下,如Cache-Control: max-age=0, stale-while-revalidate=36000000,也有可能找到應用場景。
另一個需要考慮的是,must-revalidate指令可以屏蔽stale-while-revalidate的使用,以確保始終獲取最新內容。然而,直接刪除stale-while-revalidate指令可能是更好的選擇,因為must-revalidate並不應該被使用。
如果您在特定場景中能夠應用stale-while-revalidate功能,並且已經在CDN上使用了它,不妨在下方留言分享您的經驗。