結論先講
水平擴展有天花板,天花板在 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 ❌(加機器無效)
解法
-
擴 DB 之前先算連線數:
AP 台數 × 每台 pool = 總連線數 總連線數 ≤ max_connections × 80% -
用 PgBouncer: 在 AP 和 DB 之間加一個連線池代理,AP 連 PgBouncer,PgBouncer 維護固定數量的 DB 連線。這樣加 AP 不會增加 DB 端的連線數。
-
先做垂直擴展: 在水平擴展之前,確認 免費午餐 都做了(multi-worker +93%、Redis cache +6.5 倍)。單機優化完再加機器。
K8s vs Docker Compose:1000 人以內不用 K8s
壓測數據
| 架構 | 100 VU | 500 VU | 1000 VU |
|---|---|---|---|
| Docker Compose + nginx | 0% 錯誤 | 0% 錯誤 | 0% 錯誤 |
| k3s (輕量 K8s) | 0% 錯誤 | 開始報錯 | 大量報錯 |
為什麼 k3s 反而更差
k3s 是輕量版 K8s,設計給測試和邊緣場景。在我們的壓測環境(4 CPU / 4 GB)中:
- K8s 本身吃資源: kube-apiserver、etcd、kubelet、kube-proxy 加起來吃掉 1-2 CPU 和 500MB-1GB RAM。等於你的 AP 只剩 2-3 CPU 和 3 GB RAM
- Service mesh overhead: K8s 的 ClusterIP Service 有 iptables/ipvs 的封包轉發成本
- 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 deploy | K8s |
| 需要自動 auto-scaling | K8s |
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)後的效能損失:
| Gateway | Plugin 效能損失 |
|---|---|
| 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%(微服務間) | 中 |
| K8s | 0%(效能不變,運維變好) | 高 |
先做左邊三個(零成本的免費午餐),再考慮水平擴展,最後才上 K8s。
下一篇
跨層容量規劃:從 10 人到 5000 人的技術選型地圖 — 把前端、後端、DB、Storage、Infra 五層的數據全部串起來,做一張「N 個人同時用,每層該選什麼」的完整決策表。
本系列文章
完整 68 篇目錄見 系列首頁
← 上一篇:Infra 的免費午餐:不改程式碼效能翻倍 → 下一篇:跨層容量規劃:從 10 人到 5000 人的技術選型地圖