Skip to content
所有文章 ‹ Part 10 of 11 · 從 19 個 goroutine 到 exit 137
工程 · 1 min read

keep-alive 讓重試卡在同一台:不換連線,429 等於白回

429 說「我滿了」,但 keep-alive 讓重試永遠敲同一扇門。關掉它,L4 才能重新選到有空的 pod。

429 說「我滿了」。但 keep-alive 讓你的重試永遠敲同一扇門。

L4 負載均衡的盲點

WITH keep-alive (pinned): Client TCP Pod A (429 "full") retry Pod A again ← 白打! retry Pod A again WITHOUT keep-alive (new conn each retry): Client TCP₁ Pod A (429) retry TCP₂ Pod B ✓ ← kube-proxy re-pick retry TCP₃ Pod C ✓
  • K8s Service 預設是 L4 負載均衡,決策在 TCP connection 建立時做一次(執行環境)。
  • 有 HTTP keep-alive 時,所有 request 走同一條 connection → 同一個 pod。429 retry 繼續打 滿了的那台。
  • 修法:關掉 keep-alive(每次重試開新連線),讓 kube-proxy / iptables 重新選。L4 re-pick 是隨機的 → 配合 retry + jitter。

在這個 OOM 裡的角色

呼叫端服務的 HTTP client 預設 reuse connection。截圖服務回 429 後,重試全部打回同一個 pod,等於 429 白回了。設定 max_keepalive_connections=0 後,每次重試開新 TCP → kube-proxy 有機會選到有空的 pod(用 TryAcquire 做 load shedding)。

429 + keep-alive = 一直敲同一扇關著的門。429 + 新連線 = 有機會找到開著的門。

參考來源:

延伸閱讀: 參見執行環境、共享資源的影響範圍、用 TryAcquire 做 load shedding,或回到系列總覽。

↑↓ 移動 ↵ 開啟 esc 關閉