Nginx 在逾時後強制重新驗證過時的快取

Nginx 在逾時後強制重新驗證過時的快取

Nginx反向代理快取使用中有一種情況,當;

proxy_cache_background_update on;
proxy_cache_use_stale updating;

對於同一個 URL,如果來自上游的單一回應具有 max-age,那麼當所有其他回應都是無快取時,Nginx 永遠無法從這種情況中恢復。

想像一下場景:

  1. 客戶端 -> Nginx (MISS) -> 上游200(緩存控制:無緩存)
  2. 客戶端 -> Nginx (MISS) -> 上游200(緩存控制:無緩存)
  3. 客戶端 -> Nginx (MISS) -> 上游200(緩存控制:無緩存)
  4. 客戶端 -> Nginx (MISS) -> 上游503(快取控制:最大年齡=10)
  5. 客戶端 -> Nginx(HIT,503,年齡:3)
  6. 客戶端 -> Nginx(HIT,503,年齡:8)
  7. 客戶端 -> Nginx(陳舊,503,年齡:13) ->BG上游200 (緩存控制:無緩存)
  8. 客戶端 -> Nginx(陳舊,503,年齡:18) ->BG上游200 (緩存控制:無緩存)
  9. 客戶端 -> Nginx(陳舊,503,年齡:23) ->BG上游200 (緩存控制:無緩存)
  10. ...客戶看到503永恆

在上面的場景中,上游發生了一次錯誤,並返回了 max-age(不幸的是,此行為無法幹預)。因為真正的 200 回應是無快取的,所以它永遠無法覆蓋STALE 503 並永遠給出錯誤,直到手動清除。

在網上找不到有關此情況的任何信息,所以我在這裡詢問。怎麼處理這個問題。我在用OpenResty所以我可以存取 Nginx 開源模組和 Lua。

可能的解決方案和我的研究:

  • stale-if-errorCache-Control 標頭的擴充stale-while-revalidate似乎確實解決了這個問題。不幸的是,上游標頭不允許修改(並且無法按照預期在 Nginx 處理標頭之前插入這些標頭)。

  • 使用 Lua 腳本手動設定 STALE 快取的逾時,並在超過時清除。但我更願意使用標準/Nginx 提供的解決方案。

  • 添加第二個反向代理以添加標頭stale-if-errorstale-while-revalidate默認添加(我寧願讓問題存在,而不是這樣做)。

  • 使用 Lua 來追蹤快取年齡,如果超過則將變數設為 true,然後proxy_cache_bypass從 Nginx 中使用它。 (有點灰色區域,執行順序與內容階段指令有關)

相關內容