為什麼對gRPC做負載均衡會很棘手?

SpringLeee發表於2021-02-06

在過去的幾年中,隨著微服務的增長,gRPC在這些較小的服務之間的相互通訊中獲得了很大的普及,在後臺,gRPC使用http/2在同一連線和雙工流中複用許多請求。

使用具有結構化資料的快速,輕便的二進位制協議作為服務之間的通訊介質確實很有吸引力,但是使用gRPC時需要考慮一些因素,最重要的是如何處理負載均衡。

gRPC使用粘性連線

gRPC連線是粘性的。這意味著當從客戶端到伺服器建立連線時,相同的連線將被儘可能長時間地用於許多請求(多路複用)。這樣做是為了避免所有最初的時間和資源花費在TCP握手上。因此,當客戶端獲取與伺服器例項的連線時,它將保持連線。

現在,當同一客戶端開始傳送大量請求時,它們都將轉到同一伺服器例項。而這正是問題所在,將沒有機會將負載分配給其他例項。他們都去同一個例項。

這就是為什麼粘性連線會使負載平衡變得非常困難。

以下是一些負載均衡gRPC相互通訊的方法,以及每種方法的一些細節。

1.伺服器端

當在伺服器端完成負載均衡時,會使客戶端非常精簡,並且完全不知道如何在伺服器上處理負載:

網路負載均衡器

網路負載均衡器在OSI (Open Systems Interconnection) 模型的第4層執行。因此,它非常快,可以處理更多的連線。當出現新的TCP通訊連線時,負載均衡器將選擇一個例項,並且在連線有效期內將連線路由到該單個例項。

現在請記住,gRPC連線是粘性的和持久的,因此它會在負載均衡器後面的客戶端和同一伺服器例項之間保持相同的連線,只要它可以。

現在這是問題所在:

粘性連線和自動縮放

如果單個伺服器例項上的負載(記憶體或cpu)高於自動伸縮策略,則將導致在該目標組中啟動一個新例項。

但是,目標組中的新例項將無濟於事。為什麼?同樣,因為gRPC連線是持久的且具有粘性。正在傳送大量請求的客戶端,將繼續將它們傳送到與其連線的同一伺服器例項。

因此,新的伺服器例項被啟動,但是沒有請求過載將流向新的例項。利用率高的同一臺單伺服器例項仍在接收來自客戶端的請求負載(因為客戶端一直在重用相同的連線)。

自動伸縮策略可能會不斷觸發並向目標組新增新例項(因為單個例項的cpu /記憶體過載)。但是這些新例項接收的流量幾乎為零。自動縮放策略可能會繼續觸發並可能最大化目標組中允許的例項,而實際上並未從傳送到新例項的請求中受益。

如何使用gRPC粘性連線分配負載?

為了基本上有機會分配負載,我們必須使用以下方法之一放棄粘性和持久連線:

1.客戶端定期重新連線

如果您可以控制連線的gRPC客戶端,則可以強制客戶端定期斷開連線並重新連線。此行為將迫使客戶端向負載均衡器傳送新請求,並且作為對此請求的響應,這次將返回更健康的例項。

2.伺服器定期強制斷開客戶端連線

如果您無法控制連線的gRPC客戶端,則可以在伺服器端實現類似的邏輯。使伺服器在一段時間後強行關閉連線,當它們重新連線時,它會自動使新連線進入更健康的例項。

這些方法中的任何一種都丟失了gRPC的基本優勢:可重用的連線。

DNS服務發現

同樣,我們可以將伺服器例項放置在DNS服務發現之後,而不是在Elastic Load Balancer後面。服務發現本質上是一種DNS服務,當請求進入時,它將以隨機順序返回其後面所有例項(或正常例項的子集)的IP地址列表。因此,當客戶端選擇要連線到的伺服器並進行DNS查詢時,服務發現將返回排序後的例項的IP地址。

網路負載均衡器的所有問題幾乎都適用於DNS服務發現負載均衡。當客戶端獲取到單個例項的連線時,它將堅持並繼續重用它。

2.客戶端

如果您完全控制客戶端,則可以在客戶端實現負載均衡的邏輯。使客戶端了解所有可用伺服器及其執行狀況,並選擇要連線的伺服器。這將導致客戶的邏輯負擔增加。因此,它們不僅應包含執行應做的邏輯,而且還需要實現用於負載平衡,執行狀況檢查等的邏輯。

在一種情況下,這是一個可行的選擇:如果您完全控制所有客戶端。您不能讓有故障的客戶端連線到您的服務並導致各種負載平衡問題。只需要一個有故障的客戶端就可以引起足夠的麻煩。

3. 觀察模式

按照官方gRPC負載平衡的建議,此方法使用外部負載均衡器或one-arm負載均衡器在伺服器例項之間分配流量。

客戶端與外部服務聯絡,它將返回可用伺服器,服務發現和所有其他必需資訊的列表。

理想情況下,客戶端也會有一些邏輯來幫助做出決定。這種方法很容易出現上面提到的粘性連線問題,因此需要仔細實施。

每個呼叫都將分別進行負載均衡,而不是每個連線一個,這是理想且理想的情況,它將避免具有沉重的粘性連線。

您需要實現和部署全新的專用服務,以僅負載均衡其他服務之間的gRPC連線。每項新服務都具有自己的維護,操作,監視,警報等。

結論

伺服器端負載均衡要有非常重要的考慮,我們無法從gRPC的主要優點之一中受益,後者是粘性可重用連線。

客戶端負載均衡需要對客戶端進行完全控制,如果有一個錯誤的客戶端,則可能會破壞所有計劃。

觀察模式負載均衡是對gRPC連線進行負載均衡的最合邏輯且效能最高的解決方案,但是它需要自己的完整且專用的服務,這意味著要在體系結構中實施和操作一項新服務,這些是要考慮到的。

gRPC也需要權衡取捨,瞭解折衷方案並做出相應選擇至關重要。

原文作者: majidfn
原文連結: https://majidfn.com/blog/20201222-grpc-load-balancing/

最後

歡迎掃碼關注我們的公眾號 【全球技術精選】,專注國外優秀部落格的翻譯和開源專案分享,也可以新增QQ群 897216102

為什麼對gRPC做負載均衡會很棘手?

相關文章