Engineering · 3 min read
noKeepAlive:為什麼每次都要重新連線
Go 預設的 HTTP client 重用 TCP 連線,跳過 DNS。KEDA 縮容後,舊連線會打到死掉的 Pod。一個設定就能修好。
問題
Go 的預設 HTTP client 會重用 TCP 連線。對固定伺服器來說省時間。但 Chrome Pod 不是固定伺服器。KEDA 隨時在擴縮。重用的連線可能指向一個已經消失的 Pod。
為什麼 Keep-Alive 會跳過 DNS
Keep-alive 連線是一條直通某個 Pod IP 的 TCP 管道。Client 把管道撐開。下一次 request 直接送到同一條管道,不再問 DNS。如果那個 IP 後面的 Pod 已經不在了,request 就失敗。
修復方式
一個設定。每次 request 開一條新 TCP 連線,結束就關掉。5 秒的 timeout 防止卡在連不上的 Pod。
var noKeepAliveClient = &http.Client{
Transport: &http.Transport{DisableKeepAlives: true},
Timeout: 5 * time.Second,
}
三道防線缺一不可
少掉任何一道,系統會用不同的方式壞掉。
不要加 connection pool。Pool 會保持對 Pod IP 的連線,KEDA 隨時可能把那個 Pod 收掉。Chrome Pod 的 HTTP 呼叫必須保持無 pool。
參考來源:
Related: 看提供 Pod IP 的 headless Service,或回到系列總覽。