Skip to content
All writing Part 10 of 11 · 從 19 個 goroutine 到 exit 137
Engineering · 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 + 新連線 = 有機會找到開著的門。

參考來源:

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

Tags #go #concurrency #reliability
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

// elsewhere
LinkedInMedium (lang: en)Youtube
wh:~$William Hung· © 2026 Taipei · GMT+8 · Available for collaboration