cover

使用者打開你的網站,覺得「快」或「慢」——這個感受的背後是 DNS、CDN、Load Balancer 三層的協作結果。任何一層出問題,使用者的體驗就崩了。

先講結論

DNS 提供入口、CDN 提供速度、Load Balancer 提供彈性。三者的關係是串聯的:DNS 指向 CDN,CDN 回源到 LB,LB 分配到後端服務。出事的時候要能快速切換,而「快速切換」的前提是你的 DNS TTL 夠低、你有備援的 CDN 或 LB、而且你演練過。


DNS:沒有它就沒有一切

DNS 做的事情很簡單——把域名翻成 IP。但它是整個系統的第一道入口,DNS 掛了等於所有服務都不可達。

幾個關鍵操作:

TTL 策略——日常 TTL 設 300 秒就好。要做 DNS 切換前,提前 24-48 小時把 TTL 降到 60 秒,切換完穩定後再調回來。很多人在切換當下才改 TTL,結果舊紀錄還在全世界的 DNS cache 裡,要等好幾個小時才生效。

內外分離——External DNS 對公網,Internal DNS 對內部服務。不要讓內部 IP 暴露到公網的 DNS 紀錄裡。

供應商備援——你的 DNS 供應商也會故障。大型服務至少要有多區域的 DNS 配置,或者備援供應商。


Load Balancer:L4 跟 L7 差在哪

簡單講:L4 看 TCP 封包,不懂 HTTP;L7 懂 HTTP,能根據路徑、Header 做路由。

大部分 Web 服務用 L7,因為你會需要根據 URL path 分流到不同後端:

upstream api_pool {
  server 10.0.10.11:8080 max_fails=3 fail_timeout=30s;
  server 10.0.10.12:8080 max_fails=3 fail_timeout=30s;
}
 
server {
  listen 443 ssl;
  server_name api.example.com;
 
  location /v1/ {
    proxy_pass http://api_pool;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

健康檢查一定要做,而且檢查路徑要跟服務路徑一致。我見過健康檢查打 /health 永遠回 200,但 /api/orders 已經在 500 了——因為 /health 沒有碰到 DB 連線。

常見的分配演算法:Round Robin(平均分配)、Least Connections(連線少的優先)、IP Hash(維持 session 黏著)。不確定用哪個?Round Robin 配合健康檢查就能解決大部分場景。


CDN:速度與成本的槓桿

CDN 在全球各地的邊緣節點快取你的靜態資源。使用者從最近的節點拿到檔案,不用每次都打到你的 origin server。

Cache Key 要想清楚——CDN 用什麼來判斷「這是同一份內容」?預設是 URL + Query string,但如果你的 URL 帶了不影響內容的追蹤參數(像 ?utm_source=xxx),命中率就會很低。

靜態資源長 TTL,動態內容短 TTL 或 bypass

Cache-Control: public, max-age=86400, s-maxage=604800, stale-while-revalidate=60

回源保護——設定 Origin Shield 讓 CDN 只從一個中間層回源,避免全球邊緣節點同時打爆你的 origin。

最常見的坑是:HTML 也被長時間快取了,結果部署了新版但使用者看到的還是舊頁面。然後就開始叫使用者清 cache,超專業的。


三者怎麼協作

正常情況:DNS → CDN → LB → 後端服務。

CDN 故障?切 DNS 到備援 CDN 或直連 LB。LB 故障?DNS 切到另一個 LB IP。整個區域故障?多區域 DNS 切到另一個 region。

關鍵是:這些切換你演練過嗎? 固定窗口每季做一次 DNS 災備測試。不演練的 DR 計畫就是假的。


延伸閱讀

  • Cloudflare DNS / CDN 文件
  • Nginx / HAProxy 進階設定
  • Anycast 與多區域容錯設計

網路層最玄學的 bug 是:你這邊打得通、使用者那邊打不通。然後你查了半天,發現是某個偏遠地區的 DNS resolver 還在快取三天前的舊紀錄。