多租戶 PaaS 或網站託管平台會讓大量 Host 與請求集中到同一個入口。
僅僅讓 Worker 保持輕量還不夠;KV 讀取、靜態檔案取得、快取傳播與未知 Host,都必須視為同一條請求路徑來設計。
在 KamuiDash 的公開入口,Cloudflare Worker 會從 Host 解析租戶應用程式,再依路由將請求送往動態應用程式或靜態內容交付路徑。完整架構可參考以 Cloudflare 作為入口的多租戶 PaaS 設計。
本文聚焦於如何降低共用入口產生的 KV 讀取。目標是不再為每個請求重問 KV 相同問題,而是在同一個 Cloudflare 資料中心內短暫共用已解析的路由結果。
最初的問題:結果正確,但每次都讀取
最初的路由模型刻意保持簡單。自訂網域先查詢其內部應用程式,再查詢應用程式的交付資訊;平台子網域也從 KV 解析動態或靜態路由資料。
這個模型容易理解,在低流量時也足夠。然而當整個 PaaS 的流量成長,即使應用程式完全沒有變更,同一份路由資訊仍會被重複讀取。
1. 平台擁有的 Host 不查詢網域對應 KV
第一步是停止向 KV 詢問 Host 本身已經能確定的資訊。平台 apex 與萬用字元子網域本來就能作為內部應用程式名稱;只有真正的自訂網域需要從公開 Host 轉換成內部 Host。
2. 整合動態與靜態路由記錄
動態應用程式與靜態網站原本使用不同路由表。我們將它們整合成一個路由 KV,讓一次應用程式查詢就能判斷交付類型並取得所需資料。
放在同一筆記錄
遷移時,我們先將記錄複製到新 KV,確認數量與重複項目,再切換 Worker。我們刻意移除舊讀取 fallback,避免長期存在兩個事實來源而增加故障排查難度。
3. 在 KV 之前檢查靜態內容快取
如果同一個靜態 URL 被反覆請求,就能在解析 Host 前直接回傳快取內容。因此,我們把以公開 URL 為鍵的靜態內容快取移到所有路由查詢之前。
- 解析 Host
- 讀取路由 KV
- 判斷靜態路由
- 檢查內容快取
- 取得靜態檔案
- 檢查內容快取
- 解析 Host
- 讀取路由 KV
- 取得靜態檔案
共用快取可能包含其他回應,因此由此 Worker 寫入的項目會帶有私有標記。HIT 時先驗證標記,回傳前再移除;若後段也送來同名標頭,同樣會被移除,避免內部狀態暴露給使用者。
4. 以 Route Cache 共用已解析路由
除了靜態回應內容,我們也會把 Host 解析到已驗證路由記錄的結果存入 Cache API。動態應用程式的回應內容不會共用,只快取其路由。
快取鍵由正規化後的 Host 產生,並限制在平台管理的範圍。具體內部路徑與識別資訊不對外公開。
只有狀態與交付資料通過驗證的記錄才會被儲存。缺少必要值時不會選擇隱含目的地,而是安全地停止路由;內部欄位名稱與識別資訊均省略。
5. 短暫快取已確認不存在的結果
如果只快取正常路由,對同一個不存在 Host 的重複查詢仍會到達 KV。Cloudflare 即使找不到鍵,也會計算該次 KV 操作。
因此,我們只將明確確認不存在的結果做短時間 negative cache。處理中狀態、格式錯誤記錄與上游失敗都不會被快取。
代價是:如果某個 Host 在完成註冊前就被存取,建立後仍可能短暫回傳 404。我們讓 Route Cache 與 KV 邊緣快取共用同一個 freshness budget,避免明顯增加既有傳播時間。
TTL 越短不一定越好
TTL 不應只由成本決定,而要從新路由或新內容部署後可接受的顯示時間反推。我們不會獨立延長 KV 邊緣快取、Route Cache 與靜態內容快取,而是將它們重疊時的延遲視為同一個 freshness budget。具體數值不對外公開。
Cache API 與 Workers Caching 是不同機制
這次使用的是 Worker 程式碼內操作的 Cache API。Cloudflare 另有能在 Worker 執行前直接回傳回應的 Workers Caching,兩者彼此獨立。
- Worker 請求仍會計費
- Worker CPU 會執行
- HIT 時略過 KV 與後段讀取
- Worker 請求仍會計費
- Worker CPU 不執行
- 略過 KV 與後段處理
目前的 Worker 是靜態與動態路由的共用閘道。動態回應預設使用 private,不會存入 Workers Caching。由於路由查詢是眼前最直接的成本來源,我們優先導入 Route Cache。
在快取前後都驗證資料
快取會同時加速正確值與錯誤值,因此記錄在寫入前與讀取後都必須驗證。
- 驗證結構版本 — 不會默默解讀未來的新格式。
- 只將有效狀態快取為正常路由 — 處理中記錄不會被視為健康路由。
- 要求完整交付資料 — 欄位缺失時不會選擇隱含目的地。
- 不向外暴露內部標記 — 即使同名標頭來自後段也會移除。
- 不共用動態回應 — 預設使用
Cache-Control: private。 - 404 不反射使用者路徑 — 回傳固定訊息。
先從開發環境逐步推出
路由器會影響所有租戶,因此我們依序在本機、開發環境與正式環境驗證。每次 Terraform plan 都必須只包含 Worker 的原地更新,不能混入 KV、靜態交付、DNS 或 Tunnel 的其他變更。
- 01本機測試正常、404、處理中、格式錯誤與快取失敗
- 02開發環境 plan只有預期的原地更新
- 03開發環境 URL動態、靜態與未知 Host
- 04正式環境 plan再次確認 Worker 單一變更
- 05正式環境 URL平台、自訂、靜態與 404 路由
本機測試涵蓋平台 Host、自訂網域、動態與靜態路由、正向與負向快取、處理中狀態、格式錯誤記錄與 KV miss;正式環境則以實際 URL 驗證相同的公開行為。
接下來的最佳化
路由 KV 的主要讀取削減已經完成,下一步應由實際量測決定。
- 抽樣記錄成功日誌 — 高流量下,觀測資料量本身也會成為成本。
- 更新時明確 purge — 在不延長可見傳播時間的情況下提高快取效率。
- 以多層防護處理異常流量 — 在邊緣保護資源,不只依賴快取行為。
總結
關鍵不是新增某一個快取,而是把成本最低且可靠的判斷放在最前面。
- 01Host 已知的資訊不要再詢問 KV平台擁有的 Host 可以直接辨識。
- 02整合用途相同的記錄一次讀取即可決定動態或靜態交付。
- 03先檢查內容快取靜態 HIT 可完全略過路由處理。
- 04短暫共用有效路由與 404不要為每個請求重做相同判斷。
- 05將 freshness 視為預算延長 TTL 前先設計可接受的傳播時間。
在多租戶入口,每一個小型讀取都會乘上所有租戶與請求。從 Workers、KV、Cache API 到交付路徑,設計每個請求能在哪裡停止,讓我們在不讓閘道變得難以維護的前提下降低讀取。