Skip to content
所有文章 ‹ Part 16 of 18 · Cache 不是方塊,是一條鏈
工程 · 1 min read

Proxy 不接受 HEAD,刷新永遠失敗

LB cache 用 HEAD refresh 大檔案,但用 Gin 寫的 Go proxy 只註冊 GET,於是回 405。一個框架預設不支援的 method,就讓整層 cache 失效。

LB cache 用 HEAD refresh 大檔案。我們的 proxy 只接受 GET,所以回 405,副本就一直是過期的。

上一篇的問題是:背景 refresh 為什麼一直失敗(Stale-while-revalidate:先回舊檔,背景再刷新)?我打開 proxy 的 log 和程式碼。

// router
engine.GET("/*path", RootHandler)       // 只註冊 GET

// server
engine.HandleMethodNotAllowed = true    // 路徑對、method 錯 → 405
  • Proxy 用 Go 的 Gin 框架。它對所有路徑只註冊 GET,沒有任何路由接受 HEAD。
  • HandleMethodNotAllowed = true 讓 Gin 回 405,而不是 404。
  • 雲端 storage、nginx 和 Go 標準函式庫 net/http 預設都會用 GET 的路由回答 HEAD。Gin 不會。

我在 log 裡看到的

觀察結果
進 proxy 的 HTML request每秒十幾個
其中是 HEAD、拿到 405 的75%
405 的 user agentLB cache 自己
拿到 405 最多的檔案3.5 到 4.3 MB 的 HTML
拿到 304 最多的檔案都小於 1 KB

我透過 CDN 打了 7 個 request,proxy log 在同一秒出現 7 行 HEAD 405。最糟的檔案是 3.65 MB,每 0.24 秒就被 fetch 一次。

LB cache 對大檔案改用 HEAD refresh,是我從 log 推出來的。官方文件沒有寫。

一個框架預設不支援的 method,就能讓整層 cache 失效。

延伸閱讀:一個 HTTP request、Stale-while-revalidate:先回舊檔,背景再刷新、五個零件串成一個迴圈。或回到系列總覽。

↑↓ 移動 ↵ 開啟 esc 關閉