結論先講

水平擴展有天花板,天花板在 DB 不在 AP。 2 台 AP 比 1 台快 53%,但 4 台不會比 2 台更好。原因很簡單:4 台 AP × pool=5 = 20 個 DB 連線,PG 的 max_connections 只有 100,加更多 AP 只是更多請求在排隊等 DB 連線。


水平擴展的數據

AP 台數RPS提升錯誤率
1 台6,309基準0%
2 台9,685+53%0%
4 台9,700+54%出現 timeout

2 台 → 4 台幾乎沒有提升(+1%),而且開始出現 timeout 錯誤。

瓶頸轉移的過程

1 台: AP 忙不過來 → DB 連線有空閒
      瓶頸在 AP ✅(加機器有效)

2 台: AP 閒一點 → DB 連線被用滿
      瓶頸開始轉移 ⚠️

4 台: AP 很閒 → DB 連線搶破頭 → timeout
      瓶頸在 DB ❌(加機器無效)

解法

  1. 擴 DB 之前先算連線數:

    AP 台數 × 每台 pool = 總連線數
    總連線數 ≤ max_connections × 80%
    
  2. 用 PgBouncer: 在 AP 和 DB 之間加一個連線池代理,AP 連 PgBouncer,PgBouncer 維護固定數量的 DB 連線。這樣加 AP 不會增加 DB 端的連線數。

  3. 先做垂直擴展: 在水平擴展之前,確認 免費午餐 都做了(multi-worker +93%、Redis cache +6.5 倍)。單機優化完再加機器。


K8s vs Docker Compose:1000 人以內不用 K8s

壓測數據

架構100 VU500 VU1000 VU
Docker Compose + nginx0% 錯誤0% 錯誤0% 錯誤
k3s (輕量 K8s)0% 錯誤開始報錯大量報錯

為什麼 k3s 反而更差

k3s 是輕量版 K8s,設計給測試和邊緣場景。在我們的壓測環境(4 CPU / 4 GB)中:

  1. K8s 本身吃資源: kube-apiserver、etcd、kubelet、kube-proxy 加起來吃掉 1-2 CPU 和 500MB-1GB RAM。等於你的 AP 只剩 2-3 CPU 和 3 GB RAM
  2. Service mesh overhead: K8s 的 ClusterIP Service 有 iptables/ipvs 的封包轉發成本
  3. Pod scheduling delay: Pod 啟動需要時間,auto-scaling 的反應不夠快

Docker Compose + nginx 沒有這些 overhead——nginx 直接 proxy 到 AP container,幾乎零額外成本。

那什麼時候用 K8s

場景推薦
< 100 人單機 Docker Compose
100-1000 人Docker Compose + nginx LB(2-4 台)
1000+ 人K8s(需要自動擴縮、滾動更新)
需要 zero-downtime deployK8s
需要自動 auto-scalingK8s

K8s 的價值在運維自動化,不在效能。 1000 人以內,手動管 2-4 台 Docker Compose 的成本比學 K8s 低很多。


其他 Infra 測試摘要

Infra 層有 20 項測試,除了免費午餐(第 40 篇)和水平擴展(本篇),還有一些值得提的:

TLS + HTTP/2

配置影響
HTTP → HTTPS-10~15%(TLS handshake 成本)
HTTPS + HTTP/2補回 5~8%(multiplexing)
淨影響-5~7%

HTTPS 是必須的,HTTP/2 可以部分補回 TLS 的效能損失。在 nginx 上開 HTTP/2 只需要一行 listen 443 ssl http2;

Docker bridge vs host networking

模式影響
bridge(預設)基準
host+3~5%

host networking 省掉了 Docker 的 NAT 層,但失去了網路隔離。生產環境通常用 bridge(安全性),開發/壓測環境可以用 host(效能)。

Rate Limiting:放 nginx 還是 AP

位置效能影響
nginx 層幾乎零(C 實作,超快)
AP 層(express-rate-limit)-5~10%(Node.js 處理)

Rate limiting 放 nginx 層。nginx 是 C 寫的,拒絕一個請求只要幾微秒。放在 AP 層等於讓惡意請求佔用 Node.js 的 event loop。

API Gateway:Kong vs APISIX vs Traefik

三者在開啟 plugin(auth、rate-limit、logging)後的效能損失:

GatewayPlugin 效能損失
Traefik最低(~5%)
APISIX低(~8%)
Kong中(~15%)

如果只需要簡單的 reverse proxy + rate limit,nginx 就夠了。API Gateway 的價值在 plugin 生態(auth、API key 管理、流量控制),不在效能。

序列化格式:JSON vs MessagePack vs Protobuf

格式大小速度
JSON基準基準
MessagePack-30%+15%
Protobuf-50%+30%

Protobuf 比 JSON 小 50%、快 30%。但需要定義 .proto schema + 編譯。適合微服務間通訊(gRPC 就是用 Protobuf),不適合前後端 API(前端處理 Protobuf 比 JSON 麻煩)。

Auth 策略

方式overhead
API Key(header 比對)最低(< 1ms)
JWT(驗簽)低(~2ms)
Session(Redis 查詢)中(~5ms)
OAuth(外部驗證)高(~50ms+)

JWT 的 overhead 很小。如果 JWT 驗證成為瓶頸(Spring Boot 在 500 VU 時提到),加 Redis cache JWT 驗證結果就好。


Infra 小結

優化效果複雜度
Redis cache+550%(讀多)
Multi-worker+93%
nginx keepalive+7%極低
水平擴展 2 台+53%
HTTP/2+5%
Protobuf+30%(微服務間)
K8s0%(效能不變,運維變好)

先做左邊三個(零成本的免費午餐),再考慮水平擴展,最後才上 K8s。


下一篇

跨層容量規劃:從 10 人到 5000 人的技術選型地圖 — 把前端、後端、DB、Storage、Infra 五層的數據全部串起來,做一張「N 個人同時用,每層該選什麼」的完整決策表。


本系列文章

完整 68 篇目錄見 系列首頁

← 上一篇:Infra 的免費午餐:不改程式碼效能翻倍 → 下一篇:跨層容量規劃:從 10 人到 5000 人的技術選型地圖