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

五個零件串成一個迴圈

五個零件串成一個迴圈:CDN 副本過期、沒有 bypass 規則、stale-while-revalidate、HEAD 拿到 405,最後 edge 只能保留副本 1 秒。

走 proxy 路線的大檔案,每個 request 都會重跑這個迴圈。實測中主要是大型 HTML。

前面每一篇都只是一個零件。把它們接起來,就是 HTML 一直跑回 origin 的原因(症狀:HTML、CSS、JS 一直跑回 origin)。

browserAkamaiLB cacheproxy 1GET副本過期 2GET + If-None-Match副本也過期 3304 + 舊副本(stale-while-revalidate) 4HEAD(背景) 5405副本維持過期 6200max-age=1只新鮮 1 秒 下一個 request:同樣六步再跑一次
背景的 HEAD 每次都拿到 405,副本一直沒恢復新鮮,下一個 request 又把同樣六步跑一次。
  1. Akamai 的副本過期,所以去問下一層(Cache 的新鮮度:fresh、stale 和 304)。
  2. Proxy 路線沒有 bypass 規則,所以 LB cache 接下 request(Bypass header 只在有規則的地方有效)。
  3. LB cache 立刻用舊副本回 304(Stale-while-revalidate:先回舊檔,背景再刷新)。
  4. LB cache 在背景用 HEAD refresh。第 3 步和第 4 步同時發生。
  5. Proxy 只接受 GET,所以回 405(Proxy 不接受 HEAD,刷新永遠失敗)。副本維持過期。
  6. 副本到 Akamai 時已經過期,所以 Akamai 只保留 1 秒。
步驟證據類型
1、6Akamai debug header 三次都是 TCP_REFRESH_HIT 和 max-age=1事實
4、57 個 request 對應 proxy log 同一秒的 7 行 HEAD 405事實
3304 帶的 Age 超過 3600推論,我從台灣看不到美國的 LB cache

迴圈存在時,curl 的輸出會有 max-age=1 和 TCP_REFRESH_HIT。同一個檔案改從不走 proxy 的舊網域 fetch,TTL 正常,之後都是 cache hit。

每個零件單獨看都合理。接在一起,就成了一個停不下來的迴圈。

延伸閱讀:症狀:HTML、CSS、JS 一直跑回 origin、Bypass header 只在有規則的地方有效、Stale-while-revalidate:先回舊檔,背景再刷新、Proxy 不接受 HEAD,刷新永遠失敗、我學到的:cache 不是一個方塊,是一條鏈。或回到系列總覽。

↑↓ 移動 ↵ 開啟 esc 關閉