Cloudflare Workers 邊緣運算完全指南
#建構部署 #Cloudflare #Workers #邊緣運算 #Serverless
Cloudflare Workers 是在全球邊緣節點以 V8 isolate 執行程式碼的 Serverless 平台,讓程式碼跑在離使用者最近的位置,冷啟動近乎為零。
💡 免費起步:Workers 免費方案每日 10 萬請求、頻寬無限、免信用卡即可部署。實際操作見 快速開始。
本篇屬於 Cloudflare 系列筆記,總覽見 ./cloudflare-overview.md。
目錄
- 什麼是 Cloudflare Workers?
- 運作原理
- 核心特性
- 快速開始(免費)
- 撰寫 Worker(程式模型)
- 與儲存整合(bindings)
- 免費方案額度與限制
- 什麼情境適合 Workers?
- Workers vs 傳統 Serverless
- 實戰範例
- 最佳實踐
- 常見問題
- 總結
- 延伸閱讀
什麼是 Cloudflare Workers?
Cloudflare Workers 是一種邊緣 Serverless 運算平台。開發者只需撰寫處理 HTTP 請求的函式並部署,程式碼會自動分發到 Cloudflare 全球的邊緣節點執行,無需管理伺服器或容器。
一句話理解:把一段函式部署到全球各地的網路節點,使用者的請求由地理上最近的節點處理。
核心定位是「程式碼跑在離使用者最近的邊緣節點」。傳統雲端函式通常集中在少數區域(region),請求需要跨地理距離傳輸;Workers 則把運算下放到邊緣,縮短請求路徑。
運作原理
Workers 與多數傳統 serverless 平台最大的差異在於隔離模型:它使用 V8 isolates,而不是容器或虛擬機。
V8 isolates 架構
V8 isolate 是 V8 JavaScript 引擎提供的輕量隔離單位。同一個作業系統程序內可以同時存在大量 isolate,各自擁有獨立的記憶體堆與全域狀態,彼此無法直接存取對方資料。
- 傳統 container-based serverless:每個函式實例對應一個容器或微型 VM,啟動時需要配置作業系統環境,因此有可觀的冷啟動成本。
- Workers:在已經執行中的程序內建立一個新的 V8 isolate,啟動成本極低,冷啟動近乎為零。
隔離模型對照
| 項目 | V8 isolates(Workers) | container-based(如 AWS Lambda) |
|---|---|---|
| 隔離方式 | 同一程序內以 isolate 隔離 | 各自獨立的容器 / 微型 VM |
| 冷啟動 | 近乎零 | 數十毫秒到數秒不等 |
| 啟動成本 | 極低,共用已啟動的 runtime | 需配置容器 / VM 環境 |
| 記憶體佔用 | 較小,多 isolate 共用程序 | 每實例獨立配置 |
請求如何打到最近的節點
Cloudflare 透過 Anycast 網路,讓同一個 IP 在全球多個節點對外提供服務,使用者的請求會由路由導向最近的節點:
使用者(東京)──┐
├─► Anycast 路由 ─► 最近節點(東京 PoP)─► 執行 Worker isolate ─► 回應
使用者(倫敦)──┘ └─► 最近節點(倫敦 PoP)─► 執行 Worker isolate ─► 回應
同一份 Worker 程式碼部署到全球所有節點,
請求落在哪個節點,就由該節點就近執行。
核心特性
- 全球邊緣執行:程式碼部署到 Cloudflare 全球節點,請求由就近節點處理。
- 低冷啟動:基於 V8 isolate,冷啟動近乎為零。
- 頻寬無限:免費方案不對輸出頻寬計費。
- Cron Triggers:支援定時觸發,以排程執行
scheduledhandler。 - bindings 綁定:可綁定 KV、D1、R2、Durable Objects、Queues、Secrets 等資源,在 Worker 內直接存取。
- 相容 Web 標準 API:支援
fetch、Request/Response、Web Crypto 等標準 API,而非完整 Node.js runtime。
快速開始(免費)
Workers 透過官方 CLI 工具 wrangler 進行初始化、開發與部署。
1. 安裝 wrangler
npm i -g wrangler
2. 登入 Cloudflare 帳號
wrangler login
此步驟會開啟瀏覽器完成授權。免費方案免信用卡即可部署。
3. 初始化專案
wrangler init my-worker
依互動式提示選擇樣板後,會產生包含 wrangler.toml 與入口檔的專案目錄。
4. 撰寫一個回應 fetch 的 Worker
// src/index.js
export default {
async fetch(request, env, ctx) {
return new Response("Hello from the edge!");
},
};
5. 部署
wrangler deploy
部署完成後,Cloudflare 會回傳一個可存取的 *.workers.dev URL。
撰寫 Worker(程式模型)
Worker 的標準寫法是匯出一個預設物件,內含對應事件的 handler。最常見的是處理 HTTP 請求的 fetch handler:
export default {
async fetch(request, env, ctx) {
// request:傳入的 Request 物件(Web 標準)
// env:綁定的資源(KV / D1 / R2 / Secrets ...)
// ctx:執行上下文,提供 waitUntil 等方法
const url = new URL(request.url);
return new Response(`Path: ${url.pathname}`);
},
};
三個參數的角色:
request:符合 Web 標準的Request物件。env:所有 bindings 都掛在這裡,例如env.MY_KV、env.DB、env.MY_SECRET。bindings 不寫死在程式碼中,而是在wrangler.toml設定,部署時注入。ctx:執行上下文,ctx.waitUntil()可讓非同步工作在回應送出後繼續執行。
wrangler.toml 設定範例
name = "my-worker"
main = "src/index.js"
compatibility_date = "2026-06-01"
# KV 綁定
[[kv_namespaces]]
binding = "MY_KV"
id = "<kv-namespace-id>"
env 中可存取的 bindings(KV / D1 / R2 / Secrets 等)皆由此設定檔宣告。
與儲存整合(bindings)
Worker 本身是無狀態的,持久化資料需透過 bindings 連結 Cloudflare 的儲存服務。在 wrangler.toml 宣告綁定後,即可在 env 取得對應物件:
-
KV:鍵值儲存,適合讀多寫少的快取與設定。
[[kv_namespaces]] binding = "MY_KV" id = "<kv-namespace-id>" -
D1:SQLite 相容的關聯式資料庫。
[[d1_databases]] binding = "DB" database_name = "my-db" database_id = "<d1-database-id>" -
R2:S3 相容的物件儲存。
[[r2_buckets]] binding = "MY_BUCKET" bucket_name = "my-bucket"
各儲存服務的容量、額度與用法詳見儲存篇 ./cloudflare-storage.md。
免費方案額度與限制
| 項目 | 免費方案額度 |
|---|---|
| 請求數 | 每日 100,000 requests |
| CPU 時間 | 每次呼叫 10 ms |
| 頻寬 | 無限 |
關於 CPU 時間的重要觀念:這裡限制的是 CPU 時間,不是 wall-clock(實際經過時間)。等待 I/O(例如等待外部 API 回應、等待資料庫查詢)的時間不計入 CPU 時間。換言之,一個 Worker 即使整體耗時較長,只要實際佔用 CPU 計算的時間不超過上限即可。
超出額度後的具體行為(限流、錯誤回應或計費方案差異)以官方文件為準。
周邊服務的免費額度(供參考):
- Durable Objects:強一致的有狀態物件,免費每日 100,000 requests。
- Queues:訊息佇列,免費每日 10,000 operations。
什麼情境適合 Workers?
| 情境 | 是否適合 |
|---|---|
| API 閘道 / 反向代理 / 請求改寫 | ✅ |
| 邊緣快取與內容個人化 | ✅ |
| 輕量 API 後端(搭配 D1 / KV / R2) | ✅ |
| 定時任務(Cron Triggers) | ✅ |
| 短時、I/O 為主的請求處理 | ✅ |
| 長時間 CPU 密集運算(影像批次轉碼、大型計算) | ❌ |
| 需要完整 Node.js runtime / 檔案系統的工作負載 | ❌ |
| 需長時間維持本機狀態的常駐程序 | ❌ |
Workers 的設計偏向短時、無狀態、以 I/O 為主的請求處理。需要長時間佔用 CPU 或依賴完整作業系統環境的工作負載,並不適合。
Workers vs 傳統 Serverless
以 AWS Lambda 作為傳統 serverless 的對照:
| 項目 | Cloudflare Workers | AWS Lambda |
|---|---|---|
| 隔離模型 | V8 isolate(同程序內隔離) | 微型 VM / 容器 |
| 冷啟動 | 近乎零 | 數十毫秒到數秒不等 |
| 執行時長 / CPU | 以 CPU 時間計(免費每次 10 ms) | 以 wall-clock 時長計,可設定較長逾時 |
| 執行環境 | Web 標準 API,非完整 Node.js | 完整語言 runtime(Node.js、Python 等) |
| 定價模型 | 以請求數為主,頻寬無限 | 以請求數 + 執行時長(GB-秒)計 |
兩者取捨:Workers 在冷啟動與全球分發上具優勢,適合輕量、低延遲的邊緣場景;Lambda 在 runtime 完整度與長時運算上更有彈性,適合需要完整環境或較長執行時間的工作負載。
實戰範例
範例 1:Hello World fetch handler
export default {
async fetch(request, env, ctx) {
return new Response("Hello, World!", {
headers: { "content-type": "text/plain; charset=utf-8" },
});
},
};
範例 2:綁定 KV 做簡單計數 / 快取
export default {
async fetch(request, env, ctx) {
// 讀取目前計數
const current = parseInt((await env.MY_KV.get("count")) || "0", 10);
const next = current + 1;
// 寫回 KV
await env.MY_KV.put("count", String(next));
return new Response(`Count: ${next}`);
},
};
對應的 wrangler.toml:
[[kv_namespaces]]
binding = "MY_KV"
id = "<kv-namespace-id>"
範例 3:Cron Trigger 定時任務(scheduled handler)
export default {
async scheduled(event, env, ctx) {
// event.scheduledTime:此次觸發的排定時間
// 在此執行定時工作,例如清理過期資料、彙整統計
await env.MY_KV.put("last_run", new Date(event.scheduledTime).toISOString());
},
};
在 wrangler.toml 設定觸發排程(cron 語法):
[triggers]
crons = ["0 * * * *"] # 每小時整點觸發一次
範例 4:完整 wrangler.toml 範例
name = "my-worker"
main = "src/index.js"
compatibility_date = "2026-06-01"
# 定時觸發
[triggers]
crons = ["0 * * * *"]
# KV 綁定
[[kv_namespaces]]
binding = "MY_KV"
id = "<kv-namespace-id>"
# D1 綁定
[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "<d1-database-id>"
# R2 綁定
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
最佳實踐
- CPU 時間意識:免費方案每次呼叫限 10 ms CPU 時間。避免在請求路徑中放入大量同步運算;耗時計算應考慮拆分或改用其他服務。
- 狀態外置:Worker 每次請求皆為無狀態,不要把需要持久或跨請求共享的資料放在記憶體中。改用 KV / D1 / R2 等綁定儲存。
- 以 Secrets 管理密鑰:API 金鑰、憑證等敏感值用
wrangler secret put設定為 Secrets,透過env取用,不要寫死在程式碼或wrangler.toml。 - 善用 bindings:資源以 bindings 注入,避免在程式中硬編碼連線資訊,也方便在不同環境間切換。
- 理解無狀態模型:不要假設兩次請求由同一個 isolate 處理;全域變數可能在某些請求間被重用,但不應依賴此行為來保存狀態。
常見問題
Q:Workers 跟 AWS Lambda 差在哪? A:最關鍵的差異是隔離模型。Workers 用 V8 isolate 在同一程序內隔離,冷啟動近乎為零、全球邊緣分發;Lambda 用微型 VM / 容器,提供完整語言 runtime。Workers 偏向輕量、低延遲的邊緣場景,Lambda 在 runtime 完整度與長時運算上較有彈性。
Q:為什麼冷啟動這麼快? A:因為 Workers 不需要為每個請求啟動容器或 VM,而是在已執行的程序內建立一個輕量的 V8 isolate,省去了作業系統與容器環境的啟動成本。
Q:10 ms CPU 夠用嗎? A:這是 CPU 時間而非實際經過時間,等待 I/O 不計入。對於以請求轉發、資料讀寫、輕量處理為主的邊緣場景通常足夠;但長時間 CPU 密集運算並不適合在 Workers 上執行。
Q:Worker 可以用 npm 套件嗎?
A:可以使用相容於 Workers 執行環境(Web 標準 API)的套件。Workers 並非完整 Node.js runtime,部分依賴 Node API 的套件需開啟 nodejs_compat 相容性旗標,並非所有 Node API 都支援。
Q:怎麼存資料?
A:透過 bindings 連接 Cloudflare 的儲存服務:鍵值用 KV、關聯式資料用 D1、物件 / 檔案用 R2。用法見 ./cloudflare-storage.md。
總結
核心要點
─────────────────────────────────────
• Workers = 邊緣 Serverless 運算,程式碼跑在離使用者最近的節點
• 架構 = V8 isolates(非容器 / VM),冷啟動近乎為零
• 免費 = 每日 100K 請求、每次 10 ms CPU 時間、頻寬無限
• 程式模型 = export default { fetch / scheduled }
• 狀態 = 無狀態,資料外置到 KV / D1 / R2
• 工具 = wrangler CLI + wrangler.toml
選用決策:
- 需要低延遲、全球分發的輕量請求處理 → Workers 合適。
- 需要完整 Node.js runtime 或長時間 CPU 密集運算 → 考慮傳統 serverless 或專用運算服務。
快速參考:
| 指令 | 用途 |
|---|---|
wrangler init <name> |
建立專案 |
wrangler dev |
本機開發伺服器 |
wrangler deploy |
部署到全球邊緣 |
wrangler secret put <key> |
設定 Secret |
記憶口訣:邊緣 isolate、冷啟動近零、無狀態、資料外置。
延伸閱讀
- 系列總覽:
./cloudflare-overview.md - 靜態網站部署:
./cloudflare-pages.md - 儲存(D1 / R2 / KV):
./cloudflare-storage.md - 邊緣環境的無連線池資料存取(Upstash):
../../database/upstash-guide.md
建立日期:2026-06-08 最後更新:2026-06-08