前言:為什麼後端也需要「全球化」?
假設你在台灣架設了一台 VPS 伺服器,當美國使用者訪問你的 API 時,請求需要跨越半個地球,往返延遲可能高達 200~300 毫秒。即使你的程式碼優化得再好,這個物理距離造成的延遲是無法消除的。
前端工程師早就用 CDN 解決了這個問題——把靜態檔案分發到全球各地的節點。那後端呢?
這就是 Edge Computing 要解決的問題:讓你的後端程式碼也能在全球各地的節點上執行。
什麼是 Edge Functions?
Edge Functions(邊緣函數)是部署在 CDN 邊緣節點上的輕量級運算單元。不同於傳統的單一主機架構,你的程式碼會被複製到全球數百個節點,使用者的請求會自動被路由到最近的節點執行。
運作流程
使用者請求 (台灣台北)
↓
DNS + Anycast 路由
↓
最近的邊緣節點 (台北)
↓
┌─────────────────────┐
│ 執行你的程式碼 │
│ ↓ │
│ 檢查本地快取 │
│ ├─ 命中 → 返回 │
│ └─ 未命中 ↓ │
│ 查詢邊緣資料庫 │
│ ↓ │
│ 儲存快取 + 返回 │
└─────────────────────┘
↓
回應給使用者 (~20ms)
與傳統架構相比,這種設計的優勢顯而易見:
| 架構 | 台灣使用者 | 美國使用者 | 歐洲使用者 |
|---|---|---|---|
| 傳統 VPS(台灣) | ~30ms | ~200ms | ~250ms |
| Edge Functions | ~20ms | ~20ms | ~20ms |
主流 Edge Functions 服務比較
目前市場上有幾個主要的 Edge Functions 服務,各有特色:
Cloudflare Workers
Cloudflare Workers 是目前最成熟的邊緣運算平台,擁有全球超過 300 個節點。
費用結構:
| 項目 | 免費版 | 付費版 ($5/月) |
|---|---|---|
| 請求數 | 10 萬次/天 | 1,000 萬次/月 |
| CPU 時間 | 10ms/請求 | 50ms/請求 |
| KV 讀取 | 10 萬次/天 | 1,000 萬次/月 |
| KV 寫入 | 1,000 次/天 | 100 萬次/月 |
程式碼範例——短網址重導向:
export default {
async fetch(request, env) {
const url = new URL(request.url);
const shortCode = url.pathname.slice(1);
// 1. 先查詢 KV 快取
const cachedUrl = await env.URL_CACHE.get(shortCode);
if (cachedUrl) {
// 快取命中,直接重導向(延遲 < 10ms)
return Response.redirect(cachedUrl, 301);
}
// 2. 快取未命中,查詢 D1 資料庫
const result = await env.DB.prepare(
'SELECT target_url FROM urls WHERE code = ?'
).bind(shortCode).first();
if (!result) {
return new Response('Not Found', { status: 404 });
}
// 3. 寫入快取供下次使用
await env.URL_CACHE.put(shortCode, result.target_url, {
expirationTtl: 86400 // 24 小時後過期
});
return Response.redirect(result.target_url, 301);
}
}
Vercel Edge Functions
Vercel 的邊緣函數與 Next.js 深度整合,適合前端開發者。
費用結構:
| 項目 | Hobby(免費) | Pro($20/月) |
|---|---|---|
| 執行時間 | 100 GB-Hours/月 | 1,000 GB-Hours/月 |
| 頻寬 | 100 GB/月 | 1 TB/月 |
| 邊緣中介層 | ✓ | ✓ |
| Edge Config | 基本 | 進階 |
AWS Lambda@Edge
Amazon 的解決方案,與 CloudFront CDN 緊密結合。
費用結構:
| 項目 | 費用 |
|---|---|
| 請求費 | $0.60/百萬請求 |
| 運算費 | $0.00000625125/128MB-秒 |
| 免費額度 | 每月前 100 萬請求免費 |
理解「GB-秒」計費
許多開發者第一次看到「$0.0000166667/GB-秒」這樣的計費方式會感到困惑。讓我用白話解釋:
GB-秒 = 記憶體大小 × 執行時間
想像成計程車計費:
- 記憶體就像車型(越大越貴)
- 時間就是乘車時長
- 費用 = 車型等級 × 時長 × 單價
實際計算範例
假設你的 API 配置:
- 記憶體:512 MB = 0.5 GB
- 平均執行時間:100ms = 0.1 秒
- 每月請求量:100 萬次
單次請求的 GB-秒:
0.5 GB × 0.1 秒 = 0.05 GB-秒
單次請求費用:
0.05 × $0.0000166667 = $0.00000083
每月總費用:
1,000,000 × $0.00000083 = $0.83
沒錯,一百萬次請求只要不到一美元!
更棒的是,AWS Lambda 提供每月 40 萬 GB-秒的免費額度,換算下來:
免費額度可執行次數:
400,000 ÷ 0.05 = 8,000,000 次
意思是每月 800 萬次請求完全免費!
PHP API 的記憶體需求參考
如果你習慣寫 PHP,可能會好奇 API 實際需要多少記憶體:
| 場景 | 記憶體使用 | 建議配置 |
|---|---|---|
| 極簡 API(無框架) | 2-5 MB | 128 MB |
| 輕量框架(Slim) | 8-15 MB | 256 MB |
| 中型框架(Laravel) | 20-35 MB | 512 MB |
| 大型應用 + ORM | 50-100 MB | 1024 MB |
對於一般的 CRUD API,512 MB 是最佳平衡點——既有足夠的緩衝空間,費用也相當經濟。
為什麼建議配置比實際使用量高這麼多?
你可能會好奇:如果 Slim 框架只用 8-15 MB,為什麼要配置 256 MB?這不是浪費嗎?
其實這裡有三個重要原因:
1. 記憶體與 CPU 是連動的
在 AWS Lambda 等平台,記憶體和 CPU 算力是綁定的。配置越多記憶體,分配到的 CPU 也越強:
| 記憶體配置 | CPU 分配 |
|---|---|
| 128 MB | 約 0.08 vCPU |
| 256 MB | 約 0.16 vCPU |
| 512 MB | 約 0.33 vCPU |
| 1024 MB | 約 0.66 vCPU |
這意味著即使你的程式只用 15 MB 記憶體,配置 128 MB 時 CPU 會很弱,程式反而跑得更慢。
更有趣的是,由於執行時間縮短,配置更多記憶體可能反而更便宜:
範例比較:
配置 128 MB:
- CPU 較弱,執行時間 500ms
- 費用 = 0.128 GB × 0.5 秒 × 單價 = 0.064 GB-秒
配置 256 MB:
- CPU 較強,執行時間 200ms
- 費用 = 0.256 GB × 0.2 秒 × 單價 = 0.051 GB-秒
結論:配置更高反而更便宜!
2. 預留緩衝空間避免 OOM
實際運作中,記憶體使用量會因各種因素波動:
正常請求:10-15 MB
流量尖峰時:15-25 MB
查詢大量資料:20-40 MB
未預期的例外處理:可能更高
如果記憶體配置剛好等於平均用量,一旦出現尖峰就會觸發 OOM(Out of Memory),導致函數直接崩潰、請求失敗。多配置一些緩衝空間,可以讓服務更穩定。
3. 成本差異微乎其微
讓我們算一下實際的成本差異:
假設每月 100 萬請求,平均執行時間 100ms:
128 MB 配置:
1,000,000 × 0.128 GB × 0.1 秒 × $0.0000166667 = $0.21/月
256 MB 配置:
1,000,000 × 0.256 GB × 0.1 秒 × $0.0000166667 = $0.43/月
差距只有 $0.22/月!
為了每月省不到一杯咖啡的錢,卻要承擔 CPU 太弱導致回應慢、記憶體不足導致服務崩潰的風險,顯然不划算。
最佳實踐建議
建議配置 = 實際用量 × 1.5 到 2 倍 + 向上取整到常見選項
Slim (15 MB) × 2 ≈ 30 MB → 向上取 128~256 MB
Laravel (35 MB) × 2 ≈ 70 MB → 向上取 256~512 MB
結論:選擇記憶體配置時,不要只看「夠不夠用」,還要考慮 CPU 效能和穩定性。有時候配置高一點,執行速度反而更快、費用反而更低!
邊緣快取機制詳解
前面提到的「查詢快取」到底是什麼?快取存在哪裡?要不要另外付費?
Cloudflare Workers KV
KV(Key-Value)是 Cloudflare 提供的邊緣鍵值儲存服務。它的特點是:
- 全球分散:資料會自動複製到所有邊緣節點
- 讀取快速:本地讀取延遲通常 < 10ms
- 最終一致性:寫入後約 60 秒同步到全球
費用結構:
| 項目 | 免費額度(每日) | 付費費率 |
|---|---|---|
| 讀取 | 100,000 次 | $0.50/千萬次 |
| 寫入 | 1,000 次 | $5.00/百萬次 |
| 儲存 | 1 GB | $0.50/GB/月 |
實際應用——多層快取策略:
export default {
async fetch(request, env) {
const code = new URL(request.url).pathname.slice(1);
// 第一層:Workers KV(最快,全球節點)
let target = await env.KV.get(`url:${code}`);
if (target) {
console.log('KV cache hit'); // ~5ms
return Response.redirect(target, 301);
}
// 第二層:D1 資料庫(次快,邊緣 SQLite)
const row = await env.DB.prepare(
'SELECT target FROM urls WHERE code = ?'
).bind(code).first();
if (row) {
console.log('D1 query'); // ~20ms
// 回填快取
await env.KV.put(`url:${code}`, row.target, {
expirationTtl: 86400 // 24 小時
});
return Response.redirect(row.target, 301);
}
return new Response('Not Found', { status: 404 });
}
}
打破 VPS 的限制:無伺服器資料庫
傳統觀念中,使用 Edge Functions 時如果需要讀寫資料庫,最終還是得回到中心化的 VPS。但現在有了「邊緣資料庫」,這個限制已經可以突破。
Cloudflare D1:邊緣 SQLite
D1 是 Cloudflare 推出的邊緣 SQL 資料庫,本質上是分散式的 SQLite。
費用結構:
| 項目 | 免費額度(每日) | 付費費率 |
|---|---|---|
| 讀取 | 500 萬次 | $0.001/千次 |
| 寫入 | 10 萬次 | $1.00/百萬次 |
| 儲存 | 5 GB | $0.75/GB/月 |
完整的短網址 API 範例:
export default {
async fetch(request, env) {
const url = new URL(request.url);
// POST /api/shorten - 建立短網址
if (request.method === 'POST' && url.pathname === '/api/shorten') {
const { target } = await request.json();
const code = generateShortCode(); // 產生隨機碼
await env.DB.prepare(
'INSERT INTO urls (code, target, created_at, clicks) VALUES (?, ?, ?, 0)'
).bind(code, target, Date.now()).run();
return Response.json({
success: true,
shortUrl: `https://your.domain/${code}`
});
}
// GET /:code - 重導向
const code = url.pathname.slice(1);
if (code) {
// 更新點擊數
await env.DB.prepare(
'UPDATE urls SET clicks = clicks + 1 WHERE code = ?'
).bind(code).run();
const row = await env.DB.prepare(
'SELECT target FROM urls WHERE code = ?'
).bind(code).first();
if (row) {
return Response.redirect(row.target, 301);
}
}
return new Response('Not Found', { status: 404 });
}
}
function generateShortCode() {
return Math.random().toString(36).substring(2, 8);
}
這段程式碼完全不需要 VPS——建立、讀取、統計都在邊緣完成。
PlanetScale:全球分散式 MySQL
如果你需要更強大的關聯式資料庫,PlanetScale 是很好的選擇。它基於 Vitess(YouTube 使用的技術)構建,提供全球分散式的 MySQL。
費用結構:
| 方案 | Hobby(免費) | Scaler($29/月) |
|---|---|---|
| 儲存 | 5 GB | 10 GB |
| 讀取量 | 10 億 rows/月 | 100 億 rows/月 |
| 分支功能 | 1 個 | 無限 |
連接範例:
import { connect } from '@planetscale/database';
const conn = connect({
host: 'aws.connect.psdb.cloud',
username: process.env.DB_USER,
password: process.env.DB_PASS
});
export default {
async fetch(request) {
const results = await conn.execute(
'SELECT * FROM urls WHERE code = ?',
[shortCode]
);
// PlanetScale 會自動路由到最近的區域
return Response.json(results.rows);
}
}
預算控制:避免意外帳單
使用按用量計費的服務,最擔心的就是費用失控。好消息是,各平台都提供預算控制機制。
Cloudflare Workers
最簡單——免費版有硬性上限:
- 每日 10 萬請求
- 超過直接停止服務
- 隔天自動恢復
- 絕對不會產生費用
Google Cloud
可設定預算警報 + 自動停用:
# 預算設定
budget:
amount: 10 # $10/月
alerts:
- threshold: 50% # $5 時通知
- threshold: 90% # $9 時警告
- threshold: 100% # $10 時觸發動作
# Cloud Run 配額限制
cloud_run:
max_instances: 5 # 最多 5 個容器
max_concurrency: 80 # 每容器 80 請求
AWS
需要手動設定 AWS Budgets:
- 進入 Billing Console → Budgets
- 建立 Cost Budget
- 設定每月上限(如 $5)
- 設定警報閾值(50%, 80%, 100%)
- 超過時發送 Email 通知
注意:AWS 預設不會自動停止服務,需額外設定 Lambda 自動停用。
完整方案費用對比
讓我們用一個實際的短網址專案來比較各種方案的成本:
假設條件:
- 每月 50 萬次重導向請求
- 每月 5,000 次建立短網址
- 資料量 < 1 GB
方案 A:傳統 VPS
Vultr/DigitalOcean 最小方案:
- 1 vCPU, 1 GB RAM
- 25 GB SSD
- 費用: $5-6/月
優點: 熟悉的技術棧、完全控制
缺點: 單一區域、需要維護、固定成本
方案 B:Edge Functions + 邊緣資料庫
Cloudflare Workers + D1:
- Workers: 免費版足夠(50萬 < 每日10萬×30天)
- D1: 免費版足夠(讀寫都在額度內)
- 費用: $0/月
優點: 全球快速、自動擴展、免維護
缺點: 需要學習新技術、JavaScript only
方案 C:混合架構
Cloudflare Workers(重導向)+ VPS(管理後台):
- Workers: $0(處理高頻的重導向)
- VPS: $5(處理管理功能)
- 費用: $5/月
優點: 兼顧效能與熟悉度
缺點: 需要維護兩個系統
費用總覽
| 方案 | 月費 | 全球延遲 | 維護成本 | 適合對象 |
|---|---|---|---|---|
| 傳統 VPS | $5-6 | 高 | 高 | 小型、單一區域 |
| 完全 Edge | $0-5 | 低 | 低 | 追求效能、願意學新技術 |
| 混合架構 | $5 | 中低 | 中 | 漸進式遷移 |
遷移建議:循序漸進
如果你現在有一個運行中的專案,不必一次全部改寫。建議採用階段性遷移:
第一階段:加上 CDN
現有架構 + Cloudflare Free(CDN + 基本防護)
成本: +$0
效果: 靜態資源加速、DDoS 防護
第二階段:重導向邊緣化
高頻的「讀取」操作移到 Edge:
- 短網址重導向
- 靜態 API 回應
成本: +$0(免費額度內)
效果: 核心功能全球加速
第三階段:完全無伺服器
所有功能遷移到 Edge:
- API CRUD
- 資料庫改用 D1 或 PlanetScale
- 管理後台也用 Workers
成本: $0-5/月
效果: 完全無需維護主機
常見問題釐清
在實際評估 Edge Computing 方案時,以下兩個問題經常被問到:
Q1:記憶體配置是所有請求共用,還是每個請求獨立?
每個請求都是獨立的。
當你配置 128 MB 記憶體時,這代表的是每一個請求都有自己獨立的 128 MB 和對應的 CPU 資源,而不是所有請求共用這 128 MB。
傳統 VPS(共用資源):
┌────────────────────────────────┐
│ 1 GB RAM + 1 vCPU │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Req 1│ │Req 2│ │Req 3│ ... │ ← 所有請求共用
│ └─────┘ └─────┘ └─────┘ │
└────────────────────────────────┘
Serverless(獨立資源):
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 128 MB │ │ 128 MB │ │ 128 MB │
│ 0.08 CPU │ │ 0.08 CPU │ │ 0.08 CPU │
│ Req 1 │ │ Req 2 │ │ Req 3 │
└──────────┘ └──────────┘ └──────────┘
獨立容器 獨立容器 獨立容器
這就是 Serverless 能「自動擴展」的原因——流量高時自動增加更多獨立容器,流量低時自動縮減,每個容器都只服務自己的請求。
Q2:使用邊緣資料庫後,我的資料該怎麼取回?
資料永遠是你的。 所有主流邊緣資料庫都支援標準格式的資料匯出。
| 服務 | 匯出格式 | 匯出方式 |
|---|---|---|
| Cloudflare D1 | SQLite SQL | wrangler d1 export db-name --output=backup.sql |
| PlanetScale | MySQL dump | pscale database dump db-name main --output ./backup |
| Turso | SQLite SQL | turso db shell db-name ".dump" > backup.sql |
| Supabase | PostgreSQL | pg_dump -h xxx.supabase.co -U postgres > backup.sql |
由於這些服務都是基於標準資料庫(SQLite、MySQL、PostgreSQL),匯出的資料可以直接匯入你自己的伺服器,不會被鎖定在任何平台上。
結語
Edge Computing 不是要取代傳統伺服器,而是提供了另一種選擇。對於需要全球化服務、追求極致效能、或想降低維運成本的專案,邊緣運算是值得認真考慮的方案。
從 CDN 加速靜態資源,到 Edge Functions 執行動態邏輯,再到邊緣資料庫打破資料中心的限制——現代的 Web 架構已經可以做到真正的「全球化」。
最棒的是,這一切的入門成本幾乎為零。Cloudflare Workers 的免費額度足以支撐絕大多數中小型專案,讓你可以先嘗試、再決定是否深入投入。
