网页加载出现没有合适的负载均衡器_gRPC实战--Kubernetes中使用envoy负载均衡gRPC流量...
許多剛剛接觸gRPC用戶或是剛剛把gRPC服務(wù)部署到kubernetes中感到驚訝的是,發(fā)現(xiàn)Kubernetes的默認(rèn)負(fù)載均衡通常無法與gRPC一起使用。例如,當(dāng)您使用一個簡單的gRPC Node.js微服務(wù)應(yīng)用程序并將其部署在Kubernetes上時,將發(fā)生以下情況:
盡管此處顯示的服務(wù)具有多個Pod,但從Kubernetes的CPU圖形可以清楚地看到,只有一個Pod實際上正在執(zhí)行所有工作-因為只有一個Pod正在接收任何流量。為什么?
gRPC使用性能增強的HTTP/2協(xié)議。 HTTP/2具備更低的延遲的特點,其實是通過利用單個長期存在的TCP連接并在其上多路復(fù)用請求/響應(yīng)。這會給第4層(L4)負(fù)載均衡器帶來問題,因為它們的級別太低,無法根據(jù)接收到的流量類型做出路由決策。這樣,嘗試對HTTP/2流量進行負(fù)載均衡的L4負(fù)載均衡器將打開一個TCP連接,并將所有連續(xù)的流量路由到該相同的長期連接,從而實際上取消了負(fù)載均衡。
Kubernetes的kube-proxy本質(zhì)上是一個L4負(fù)載均衡器,因此我們不能依靠它來均衡微服務(wù)之間的gRPC調(diào)用。
gRPC負(fù)載均衡方式
實際上gRPC負(fù)載均衡有以下兩種實現(xiàn)方式:
- Proxy(代理負(fù)載均衡在某些文獻中也稱為服務(wù)器端負(fù)載均衡)
- Client side
在代理負(fù)載均衡與客戶端負(fù)載均衡之間進行選擇其實是結(jié)構(gòu)的選擇。在代理負(fù)載均衡中,客戶端將RPC發(fā)送給負(fù)載均衡器(LB)代理。 LB將RPC調(diào)用分發(fā)到實現(xiàn)了實際服務(wù)調(diào)用邏輯的可用后端服務(wù)器之一。 LB跟蹤每個后端的負(fù)載,并實現(xiàn)用于公平分配負(fù)載的算法。客戶端本身不了解后端服務(wù)器。客戶可能不受信任。此體系結(jié)構(gòu)通常用于面向用戶的服務(wù),開放式Internet的客戶端可以將其連接到數(shù)據(jù)中心中的服務(wù)器,如下圖所示。在這種情況下,客戶端向LB(#1)發(fā)出請求。 LB將請求傳遞給后端之一(#2),后端將報告加載到LB(#3)。
在客戶端負(fù)載均衡中,客戶端知道多個后端服務(wù)器,并為每個RPC選擇一個。客戶端從后端服務(wù)器獲取負(fù)載報告,并且客戶端實施負(fù)載均衡算法。在更簡單的配置中,不考慮服務(wù)器負(fù)載,客戶端只能在可用服務(wù)器之間進行輪詢。如下圖所示。如您所見,客戶端向特定后端(#1)發(fā)出請求。后端通常在執(zhí)行客戶端RPC的同一連接上以負(fù)載信息(#2)進行響應(yīng)。客戶端然后更新其內(nèi)部狀態(tài)。
下邊是兩種模式的對比分析:
ProxyClient Side優(yōu)勢客戶端可以專心業(yè)務(wù)邏輯,無需感知后端,與不受信任的客戶端一起使用高性能,因為少了一層代理劣勢延遲更高,LB吞吐量可能會限制可伸縮性客戶端變復(fù)雜,客戶端跟蹤服務(wù)器的負(fù)載和運行狀況,客戶端實現(xiàn)負(fù)載均衡算法,每個語言的實現(xiàn)和維護負(fù)擔(dān),客戶端需要被信任,或者信任邊界需要由后備LB處理。
為什么不選擇客戶端負(fù)載均衡方式?
使用gRPC客戶端負(fù)載均衡器,該負(fù)載均衡器被嵌入到gRPC客戶端庫中。這樣,每個客戶端微服務(wù)都可以執(zhí)行自己的負(fù)載均衡。但是,最終的客戶非常脆弱,需要大量的自定義代碼來提供任何形式的彈性,指標(biāo)或日志記錄,所有這些我們都需要針對管道中使用的每種不同語言重復(fù)多次。
而且在云原生時代,整個基礎(chǔ)架構(gòu)升級,表現(xiàn)為
- 越來越多的公司采用了kubernetes
- 以istio為代表的service mesh服務(wù)治理方案成為一個趨勢
- dapper的出現(xiàn),代表著不斷將基礎(chǔ)架構(gòu)的功能放到代理層執(zhí)行,減小基礎(chǔ)架構(gòu)組件升級對業(yè)務(wù)代碼的影響
選擇代理的負(fù)載均衡模式,對于擁抱云原生的公司更加有意義和可拓展性。
我們真正需要的是更智能的負(fù)載均衡器。
選擇更智能的復(fù)雜均衡代理
我們需要第7層(L7)負(fù)載均衡器,因為它們在應(yīng)用程序?qū)舆\行,并且可以檢查流量以做出路由決策。最重要的是,它們可以支持HTTP/2協(xié)議。
L7負(fù)載均衡器有很多不同的選項,包括NGINX和HAProxy,但事實證明,大多數(shù)選項太過沉重,無法輕松加入我們的微服務(wù)架構(gòu)。我們將選擇權(quán)縮減為兩個關(guān)鍵競爭者-Envoy和Linkerd。兩者都是在考慮微服務(wù)架構(gòu)的情況下開發(fā)的,并且都支持gRPC。
雖然兩個代理都有許多理想的功能,但我們最終的決定權(quán)還是取決于代理的范圍。為此,有一個明顯的贏家。特使很小。它使用C ++ 11編寫,沒有基于Java的Linkerd附帶的企業(yè)級功能。
確定Envoy之后,我們便開始深入研究其功能集,并且有很多值得一看的地方。
Envoy由Lyft編寫和開源,是多年來與通常在微服務(wù)體系結(jié)構(gòu)中發(fā)生的復(fù)雜路由問題作斗爭的直接結(jié)果。它實質(zhì)上是為解決我們的問題而設(shè)計的,并且具有:
- 雙向均支持HTTP/2和SSL
- 高透明度和出色的性能
- 成熟的文檔集
- 不依賴任何給定的語言
而且新版本的envoy將會支持wasm,意味著未來的很多擴展可以直接使用你熟悉的語言來完成,而且具備原生的性能。
使Envoy適應(yīng)我們的基礎(chǔ)架構(gòu)
在您的架構(gòu)中,如果暫時沒有使用service mesh。可以采取下面的方案。
在Kubernetes中,一組一個或多個容器被稱為Pod。可以復(fù)制Pod以提供擴展,并封裝在稱為服務(wù)的抽象中,這些抽象為訪問基礎(chǔ)Pod提供了穩(wěn)定的IP地址。從Kubernetes 1.2開始,請求服務(wù)IP的默認(rèn)行為是將返回一個隨機的后端Pod。但是,您可以將服務(wù)重新配置為headless的,以便服務(wù)IP將返回可用的pod IP的整個列表,從而使您能夠執(zhí)行自己的服務(wù)發(fā)現(xiàn)。
Envoy被設(shè)計為作為Sidecar容器運行,并與客戶端容器并排放置,以模塊化的方式補充了其功能。在Kubernetes中,這轉(zhuǎn)換為在同一容器中運行客戶端容器和Envoy容器。我們將服務(wù)配置為headless的,以便為Envoy提供端點以用于服務(wù)發(fā)現(xiàn)。而且由于Envoy輸出了大量指標(biāo),因此我們能夠輕松觀察到連續(xù)gRPC調(diào)用的循環(huán)負(fù)載均衡,以確認(rèn)其按預(yù)期運行。
最終效果如下:
當(dāng)然最終的方案是service mesh。除了可以解決gRPC負(fù)載均衡的問題,會帶來更多的優(yōu)勢。
總結(jié)
以上是生活随笔為你收集整理的网页加载出现没有合适的负载均衡器_gRPC实战--Kubernetes中使用envoy负载均衡gRPC流量...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中dir用法_Python内
- 下一篇: 枚举类型是怎样定义的?有什么用途?_新型