後端也有 CDN?深入淺出 Edge Computing 邊緣運算

當你的前端透過 CDN 讓全球使用者都能快速載入靜態檔案,有沒有想過——後端程式碼是否也能享受同樣的待遇?答案是肯定的,這就是 Edge Computing(邊緣運算)。

前言:為什麼後端也需要「全球化」?

假設你在台灣架設了一台 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 提供的邊緣鍵值儲存服務。它的特點是:

  1. 全球分散:資料會自動複製到所有邊緣節點
  2. 讀取快速:本地讀取延遲通常 < 10ms
  3. 最終一致性:寫入後約 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:

  1. 進入 Billing Console → Budgets
  2. 建立 Cost Budget
  3. 設定每月上限(如 $5)
  4. 設定警報閾值(50%, 80%, 100%)
  5. 超過時發送 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 的免費額度足以支撐絕大多數中小型專案,讓你可以先嘗試、再決定是否深入投入。


延伸閱讀