Cloudflare Workers 邊緣運算完全指南

在全球邊緣節點以 V8 isolate 執行的 Serverless 運算,免費每日十萬請求、頻寬無限。

Cloudflare Workers 邊緣運算完全指南

#建構部署 #Cloudflare #Workers #邊緣運算 #Serverless

Cloudflare Workers 是在全球邊緣節點以 V8 isolate 執行程式碼的 Serverless 平台,讓程式碼跑在離使用者最近的位置,冷啟動近乎為零。

💡 免費起步:Workers 免費方案每日 10 萬請求、頻寬無限、免信用卡即可部署。實際操作見 快速開始

本篇屬於 Cloudflare 系列筆記,總覽見 ./cloudflare-overview.md


目錄


什麼是 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:支援定時觸發,以排程執行 scheduled handler。
  • bindings 綁定:可綁定 KV、D1、R2、Durable Objects、Queues、Secrets 等資源,在 Worker 內直接存取。
  • 相容 Web 標準 API:支援 fetchRequest / 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_KVenv.DBenv.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、冷啟動近零、無狀態、資料外置。


延伸閱讀


建立日期:2026-06-08 最後更新:2026-06-08

🔗相關文章