Cloudflare Workers 支援正式環境隨選 CPU/記憶體 profiling
Cloudflare Blog · 2026-10-09
Workers 與 Durable Objects 過去只能在本機用 Chrome DevTools 做 profiling,現在可以直接對正在跑的正式版本抓 CPU 或 heap profile,並在 Workers Observability 頁面看 flamegraph。這等於補上「log 和 metrics 只說資源用量高,卻不說是哪段程式」的缺口。
原本的問題
本機 profiling 吃不到正式環境的流量型態,量到的熱點常與線上不同。線上只剩聚合 metrics 與 log,能看出 CPU 或記憶體偏高,看不出是哪個函式造成,只能猜、改、重新部署再觀察。
使用方式
三種入口都能下指令:CLI(需要 cf 套件)、Dashboard 的 Observability 分頁選「Flamegraph」,或直接呼叫 API。TypeScript Worker 建議先開啟 source maps,否則函式名稱會被混淆。
cf workers versions profile latest \
--worker-id "$WORKER_ID_OR_NAME" \
--duration-ms 5000 \
--profile-type cpu > worker-cpu.pprof
# API 版本
POST /accounts/<account_id>/workers/workers/<worker_name>/versions/latest/profile
{"duration_ms":5000,"profile_type":"cpu"}輸出是 .pprof 檔,可下載;dashboard 另有表格檢視,依 sample 數排序函式。
不中斷服務的抓取方式
難點在路由:Workers 可能被複製到多個資料中心與機器,Durable Objects 還會動態搬移。系統因此先找出該版本最近在哪個資料中心執行、isolate 是否仍載入、是否專屬於該帳號,Durable Object 則依名稱導向持有它的機器。抓取本身不會另開 isolate,所以流量太低的 Worker 很難抓到東西。
CPU profile 的流程:
- 取得 isolate 與其 lock,建立 V8 CPU profiler,以 1 ms 間隔開始取樣;
- 釋放 lock,請求照常進來,等待指定時長;
- 重新取得 lock 停止取樣,再釋放 lock,序列化在臨界區外進行。
文中的兩個實例
第一個是綁定 R2 的 Worker,抓 50 秒 CPU profile。表格檢視中 genericR2JsonReplacer 佔超過 5% CPU:它是遞迴函式,而 JSON.stringify 本來就會對每個節點呼叫 replacer,兩邊都在走樹,五層深的值會被處理五次。移除重複走訪後該函式快 2.7 倍。另有一個重複呼叫的 metrics 單獨佔約 1%,存成變數即可。
第二個是記憶體:某內部 Worker 的 P999 約 133 MB,超過 128 MB 上限而頻繁出現「Exceeded Memory」驅逐。heap profile 顯示 Prometheus instrumentation 佔約 66.7% 的配置,原本以為已停用,其實只停了一半。移除後:
| 百分位 | 修改前(MB) | 修改後(MB) |
|---|---|---|
| P50 | 70 | 54 |
| P90 | 94 | 79 |
| P99 | 113 | 97 |
| P999 | 133 | 118 |
影響範圍與限制
會直接受益的是正式環境遇到 CPU 超時或「Exceeded Memory」的 Workers/Durable Objects 團隊:現在不必改碼重佈署就能定位熱點。要注意三件事:
- 必須手動觸發,短暫發生的異常時段容易錯過;
- 記憶體 profiler 只看到抓取視窗內的配置,啟動階段的配置不在其中,啟動期的記憶體問題仍需其他手段;
- 抓取期間版本要有實際流量,請選已部署且有請求的版本。
Cloudflare 表示正在做 continuous profiling,會自動取樣並在 dashboard 探索,文中未公布時程。操作細節見官方 profiling 文件。