「長連接」的擴展與負載平衡

Service 在處理「應用層」的請求時,Pod 之間的可能出現負載不均勻現象。探討如何善用長連接的優勢,同時避免系統負載不均衡的解法

「長連接」的擴展與負載平衡

「長連接」的擴展與負載平衡

長連接的優勢與問題

Kubernetes Service 是利用 Iptables 來將流量基於 L3 與 L4 欄位來分散至不同 Pod 上。因此每當要建立新的連線時便會隨機分配至其中一個 Pod 來服務。聽起來非常理想,但實際上在處理 L7 的請求時,這樣做法卻可能導致 Pod 之間的負載發生不均勻的現象?!

關鍵在於「長連接建立後,無法重新分配至新 Pod 上

長連接最為人熟知的就是 HTTP Keep-Alive,當底層 TCP 連線建立後未來的 HTTP 請求會透過同條連線傳輸,避免每次請求都需要重新建立連線,從而減少反應時間。

面對後端服務有多個機器同時運作時,由於已經和某台機器建立長連接連線,使得請求無法分散至所有機器上。若多數請求送到同台機器時,便會拉高整體服務延遲

常見解決方案

Client-side load balancing

利用 Headless Service 取得後端服務 IP 列表,自行定時維護長連線的連接池 (connection pool)。

優點:

  • 概念相當容易理解
  • 適用於絕大部分協議,且部分 library 已經實作可以直接使用

缺點:

  • 額外花費心思來管理連接池內的連線健康狀況

Service mesh

服務網格是近年來出現的新概念,透過攔截連線轉發至「邊車容器」後,由其處理後續的事宜。

邊車容器角色類似於 Proxy,因此服務建立長連接的對象從原本的後端機器改為 Pod 內的邊車容器,而後端的連接池則由邊車容器自行維護。如此就可以省去維護連線的困擾,並且在不損失長連接的優點下將連線分散。

優點:

  • 透明度高,可以在不改動系統程式下達成
  • 系統網路拓樸可視化 (distributed tracing)
  • 可調整項目多,比如說 rate limit、authZ/N

缺點:

  • 支援的協議少,如 HTTP、gRPC
  • 連線異常時,需要偵錯的地方增加
  • 請求經過的 hop 數量上升,提高延遲

原文網頁