为什么对gRPC做负载均衡会很棘手?
在過去的幾年中,隨著微服務(wù)的增長,gRPC在這些較小的服務(wù)之間的相互通信中獲得了很大的普及,在后臺,gRPC使用http/2在同一連接和雙工流中復(fù)用許多請求。
使用具有結(jié)構(gòu)化數(shù)據(jù)的快速,輕便的二進(jìn)制協(xié)議作為服務(wù)之間的通信介質(zhì)確實很有吸引力,但是使用gRPC時需要考慮一些因素,最重要的是如何處理負(fù)載均衡。
gRPC使用粘性連接
gRPC連接是粘性的。這意味著當(dāng)從客戶端到服務(wù)器建立連接時,相同的連接將被盡可能長時間地用于許多請求(多路復(fù)用)。這樣做是為了避免所有最初的時間和資源花費在TCP握手上。因此,當(dāng)客戶端獲取與服務(wù)器實例的連接時,它將保持連接。
現(xiàn)在,當(dāng)同一客戶端開始發(fā)送大量請求時,它們都將轉(zhuǎn)到同一服務(wù)器實例。而這正是問題所在,將沒有機(jī)會將負(fù)載分配給其他實例。他們都去同一個實例。
這就是為什么粘性連接會使負(fù)載平衡變得非常困難。
以下是一些負(fù)載均衡gRPC相互通信的方法,以及每種方法的一些細(xì)節(jié)。
1.服務(wù)器端
當(dāng)在服務(wù)器端完成負(fù)載均衡時,會使客戶端非常精簡,并且完全不知道如何在服務(wù)器上處理負(fù)載:
網(wǎng)絡(luò)負(fù)載均衡器
網(wǎng)絡(luò)負(fù)載均衡器在OSI (Open Systems Interconnection) 模型的第4層運行。因此,它非常快,可以處理更多的連接。當(dāng)出現(xiàn)新的TCP通信連接時,負(fù)載均衡器將選擇一個實例,并且在連接有效期內(nèi)將連接路由到該單個實例。
現(xiàn)在請記住,gRPC連接是粘性的和持久的,因此它會在負(fù)載均衡器后面的客戶端和同一服務(wù)器實例之間保持相同的連接,只要它可以。
現(xiàn)在這是問題所在:
粘性連接和自動縮放
如果單個服務(wù)器實例上的負(fù)載(內(nèi)存或cpu)高于自動伸縮策略,則將導(dǎo)致在該目標(biāo)組中啟動一個新實例。
但是,目標(biāo)組中的新實例將無濟(jì)于事。為什么?同樣,因為gRPC連接是持久的且具有粘性。正在發(fā)送大量請求的客戶端,將繼續(xù)將它們發(fā)送到與其連接的同一服務(wù)器實例。
因此,新的服務(wù)器實例被啟動,但是沒有請求過載將流向新的實例。利用率高的同一臺單服務(wù)器實例仍在接收來自客戶端的請求負(fù)載(因為客戶端一直在重用相同的連接)。
自動伸縮策略可能會不斷觸發(fā)并向目標(biāo)組添加新實例(因為單個實例的cpu /內(nèi)存過載)。但是這些新實例接收的流量幾乎為零。自動縮放策略可能會繼續(xù)觸發(fā)并可能最大化目標(biāo)組中允許的實例,而實際上并未從發(fā)送到新實例的請求中受益。
如何使用gRPC粘性連接分配負(fù)載?
為了基本上有機(jī)會分配負(fù)載,我們必須使用以下方法之一放棄粘性和持久連接:
1.客戶端定期重新連接
如果您可以控制連接的gRPC客戶端,則可以強制客戶端定期斷開連接并重新連接。此行為將迫使客戶端向負(fù)載均衡器發(fā)送新請求,并且作為對此請求的響應(yīng),這次將返回更健康的實例。
2.服務(wù)器定期強制斷開客戶端連接
如果您無法控制連接的gRPC客戶端,則可以在服務(wù)器端實現(xiàn)類似的邏輯。使服務(wù)器在一段時間后強行關(guān)閉連接,當(dāng)它們重新連接時,它會自動使新連接進(jìn)入更健康的實例。
這些方法中的任何一種都丟失了gRPC的基本優(yōu)勢:可重用的連接。
DNS服務(wù)發(fā)現(xiàn)
同樣,我們可以將服務(wù)器實例放置在DNS服務(wù)發(fā)現(xiàn)之后,而不是在Elastic Load Balancer后面。服務(wù)發(fā)現(xiàn)本質(zhì)上是一種DNS服務(wù),當(dāng)請求進(jìn)入時,它將以隨機(jī)順序返回其后面所有實例(或正常實例的子集)的IP地址列表。因此,當(dāng)客戶端選擇要連接到的服務(wù)器并進(jìn)行DNS查找時,服務(wù)發(fā)現(xiàn)將返回排序后的實例的IP地址。
網(wǎng)絡(luò)負(fù)載均衡器的所有問題幾乎都適用于DNS服務(wù)發(fā)現(xiàn)負(fù)載均衡。當(dāng)客戶端獲取到單個實例的連接時,它將堅持并繼續(xù)重用它。
2.客戶端
如果您完全控制客戶端,則可以在客戶端實現(xiàn)負(fù)載均衡的邏輯。使客戶端了解所有可用服務(wù)器及其運行狀況,并選擇要連接的服務(wù)器。這將導(dǎo)致客戶的邏輯負(fù)擔(dān)增加。因此,它們不僅應(yīng)包含執(zhí)行應(yīng)做的邏輯,而且還需要實現(xiàn)用于負(fù)載平衡,運行狀況檢查等的邏輯。
在一種情況下,這是一個可行的選擇:如果您完全控制所有客戶端。您不能讓有故障的客戶端連接到您的服務(wù)并導(dǎo)致各種負(fù)載平衡問題。只需要一個有故障的客戶端就可以引起足夠的麻煩。
3. 觀察模式
按照官方gRPC負(fù)載平衡的建議,此方法使用外部負(fù)載均衡器或one-arm負(fù)載均衡器在服務(wù)器實例之間分配流量。
客戶端與外部服務(wù)聯(lián)系,它將返回可用服務(wù)器,服務(wù)發(fā)現(xiàn)和所有其他必需信息的列表。
理想情況下,客戶端也會有一些邏輯來幫助做出決定。這種方法很容易出現(xiàn)上面提到的粘性連接問題,因此需要仔細(xì)實施。
每個調(diào)用都將分別進(jìn)行負(fù)載均衡,而不是每個連接一個,這是理想且理想的情況,它將避免具有沉重的粘性連接。
您需要實現(xiàn)和部署全新的專用服務(wù),以僅負(fù)載均衡其他服務(wù)之間的gRPC連接。每項新服務(wù)都具有自己的維護(hù),操作,監(jiān)視,警報等。
結(jié)論
服務(wù)器端負(fù)載均衡要有非常重要的考慮,我們無法從gRPC的主要優(yōu)點之一中受益,后者是粘性可重用連接。
客戶端負(fù)載均衡需要對客戶端進(jìn)行完全控制,如果有一個錯誤的客戶端,則可能會破壞所有計劃。
觀察模式負(fù)載均衡是對gRPC連接進(jìn)行負(fù)載均衡的最合邏輯且性能最高的解決方案,但是它需要自己的完整且專用的服務(wù),這意味著要在體系結(jié)構(gòu)中實施和操作一項新服務(wù),這些是要考慮到的。
gRPC也需要權(quán)衡取舍,了解折衷方案并做出相應(yīng)選擇至關(guān)重要。
原文作者: majidfn 原文鏈接:?https://majidfn.com/blog/20201222-grpc-load-balancing/[1]
最后
歡迎掃碼關(guān)注我們的公眾號 【全球技術(shù)精選】,專注國外優(yōu)秀博客的翻譯和開源項目分享,也可以添加QQ群 897216102
References
[1]?https://majidfn.com/blog/20201222-grpc-load-balancing/:?"https://majidfn.com/blog/20201222-grpc-load-balancing/"
總結(jié)
以上是生活随笔為你收集整理的为什么对gRPC做负载均衡会很棘手?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自定义 ocelot 中间件输出自定义错
- 下一篇: 使用 Tye 辅助开发 k8s 应用竟如