AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

在 Kubernetes 環境中實現 gRPC 負載均衡

來源: 責編: 時間:2023-10-17 09:38:22 266觀看
導讀前言前段時間寫過一篇 gRPC 的入門文章,在最后還留了一個坑沒有填:圖片也就是 gRPC 的負載均衡問題,因為當時的業務請求量不算大,再加上公司沒有對 Istio 這類服務網格比較熟悉的大牛,所以我們也就一直拖著沒有解決,依然只

前言

前段時間寫過一篇 gRPC 的入門文章,在最后還留了一個坑沒有填:gZZ28資訊網——每日最新資訊28at.com

圖片圖片gZZ28資訊網——每日最新資訊28at.com

也就是 gRPC 的負載均衡問題,因為當時的業務請求量不算大,再加上公司沒有對 Istio 這類服務網格比較熟悉的大牛,所以我們也就一直拖著沒有解決,依然只是使用了 kubernetes 的 service 進行負載,好在也沒有出什么問題。gZZ28資訊網——每日最新資訊28at.com

由于現在換了公司后也需要維護公司的服務網格服務,結合公司內部對 Istio 的使用現在終于不再停留在理論階段了。gZZ28資訊網——每日最新資訊28at.com

所以也終有機會將這個坑填了。gZZ28資訊網——每日最新資訊28at.com

gRPC 負載均衡

負載不均衡

原理

先來回顧下背景,為什么會有 gRPC 負債不均衡的問題。由于 gRPC 是基于 HTTP/2 協議的,所以客戶端和服務端會保持長鏈接,一旦鏈接建立成功后就會一直使用這個連接處理后續的請求。gZZ28資訊網——每日最新資訊28at.com

圖片圖片gZZ28資訊網——每日最新資訊28at.com

除非我們每次請求之后都新建一個連接,這顯然是不合理的。gZZ28資訊網——每日最新資訊28at.com

所以要解決 gRPC 的負載均衡通常有兩種方案:gZZ28資訊網——每日最新資訊28at.com

  • 服務端負載均衡
  • 客戶端負載均衡 在 gRPC 這個場景服務端負載均衡不是很合適,所有的請求都需要經過一個負載均衡器,這樣它就成為整個系統的瓶頸,所以更推薦使用客戶端負載均衡。

客戶端負載均衡目前也有兩種方案,最常見也是傳統方案。gZZ28資訊網——每日最新資訊28at.com

圖片圖片gZZ28資訊網——每日最新資訊28at.com

這里以 Dubbo 的調用過程為例,調用的時候需要從服務注冊中心獲取到提供者的節點信息,然后在客戶端本地根據一定的負載均衡算法得出一個節點然后發起請求。gZZ28資訊網——每日最新資訊28at.com

換成 gRPC 也是類似的,這里以 go-zero 負載均衡的原理為例:gZZ28資訊網——每日最新資訊28at.com

圖片圖片gZZ28資訊網——每日最新資訊28at.com

gRPC 官方庫也提供了對應的負載均衡接口,但我們依然需要自己維護服務列表然后在客戶端編寫負載均衡算法,這里有個官方 demo:gZZ28資訊網——每日最新資訊28at.com

https://github.com/grpc/grpc-go/blob/87eb5b7502493f758e76c4d09430c0049a81a557/examples/features/load_balancing/client/main.gogZZ28資訊網——每日最新資訊28at.com

但切換到 kubernetes 環境中時再使用以上的方式就不夠優雅了,因為我們使用 kubernetes 的目的就是不想再額外的維護這個客戶端包,這部分能力最好是由 kubernetes 自己就能提供。gZZ28資訊網——每日最新資訊28at.com

但遺憾的是 kubernetes 提供的 service 只是基于 L4 的負載,所以我們每次請求的時候都只能將請求發往同一個 Provider 節點。gZZ28資訊網——每日最新資訊28at.com

測試

這里我寫了一個小程序來驗證負債不均衡的示例:gZZ28資訊網——每日最新資訊28at.com

// Create gRPC servergo func() {     var port = ":50051"     lis, err := net.Listen("tcp", port)     if err != nil {        log.Fatalf("failed to listen: %v", err)     }     s := grpc.NewServer()     pb.RegisterGreeterServer(s, &server{})     if err := s.Serve(lis); err != nil {        log.Fatalf("failed to serve: %v", err)     } else {        log.Printf("served on %s /n", port)     }  }()// server is used to implement helloworld.GreeterServer.  type server struct {     pb.UnimplementedGreeterServer  }    // SayHello implements helloworld.GreeterServer  func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {     log.Printf("Received: %v", in.GetName())     name, _ := os.Hostname()     // Return hostname of Server   return &pb.HelloReply{Message: fmt.Sprintf("hostname:%s, in:%s", name, in.Name)}, nil  }

使用同一個 gRPC 連接發起一次 gRPC 請求,服務端會返回它的 hostnamegZZ28資訊網——每日最新資訊28at.com

var (     once sync.Once     c    pb.GreeterClient  )  http.HandleFunc("/grpc_client", func(w http.ResponseWriter, r *http.Request) {     once.Do(func() {        service := r.URL.Query().Get("name")        conn, err := grpc.Dial(fmt.Sprintf("%s:50051", service), grpc.WithInsecure(), grpc.WithBlock())        if err != nil {           log.Fatalf("did not connect: %v", err)        }        c = pb.NewGreeterClient(conn)     })       // Contact the server and print out its response.     name := "world"     ctx, cancel := context.WithTimeout(context.Background(), time.Second)     defer cancel()     g, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})     if err != nil {        log.Fatalf("could not greet: %v", err)     }     fmt.Fprint(w, fmt.Sprintf("Greeting: %s", g.GetMessage()))  })

創建一個 service 用于給 gRPC 提供域名:gZZ28資訊網——每日最新資訊28at.com

apiVersion: v1  kind: Service  metadata:    name: native-tools-2spec:    selector:      app: native-tools-2  ports:      - name: http        port: 8081        targetPort: 8081      - name: grpc        port: 50051        targetPort: 50051

同時將我們的 gRPC server 部署三個節點,再部署了一個客戶端節點:gZZ28資訊網——每日最新資訊28at.com

? k get podNAME                                READY   STATUS    RESTARTSnative-tools-2-d6c454689-52wgd      1/1     Running   0              native-tools-2-d6c454689-67rx4      1/1     Running   0              native-tools-2-d6c454689-zpwxt      1/1     Running   0              native-tools-65c5bd87fc-2fsmc       2/2     Running   0

我們進入客戶端節點執行多次 grpc 請求:gZZ28資訊網——每日最新資訊28at.com

k exec -it native-tools-65c5bd87fc-2fsmc bashGreeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2

會發現每次請求的都是同一個節點 native-tools-2-d6c454689-zpwxt,這也就證明了在 kubernetes 中直接使用 gRPC 負載是不均衡的,一旦連接建立后就只能將請求發往那個節點。gZZ28資訊網——每日最新資訊28at.com

使用 Istio

Istio 可以拿來解決這個問題,我們換到一個注入了 Istio 的 namespace 下還是同樣的 代碼,同樣的 service 資源進行測試。gZZ28資訊網——每日最新資訊28at.com

關于開啟 namespace 的 Istio 注入會在后續更新,現在感興趣的可以查看下官方文檔:https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/gZZ28資訊網——每日最新資訊28at.com

Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-nz8h5, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-nz8h5, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2

可以發現同樣的請求已經被負載到了多個 server 后端,這樣我們就可以不再單獨維護一個客戶端 SDK 的情況下實現了負載均衡。gZZ28資訊網——每日最新資訊28at.com

原理

其實本質上 Istio 也是客戶端負載均衡的一種實現。gZZ28資訊網——每日最新資訊28at.com

圖片圖片gZZ28資訊網——每日最新資訊28at.com

以 Istio 的架構圖為例:gZZ28資訊網——每日最新資訊28at.com

  • 每一個 Pod 下會新增一個 Proxy 的 container,所有的流量入口和出口都會經過它。
  • 它會從控制平面 Istiod 中拿到服務的注冊信息,也就是 kubernetes 中的 service。
  • 發生請求時由 proxy 容器中的 Envoy 進行最終的負載請求。

可以在使用了 Istio 的 Pod 中查看到具體的容器:gZZ28資訊網——每日最新資訊28at.com

? k get pod native-tools-2-5fbf46cf54-5m7dl -n istio-test-2 -o json | jq '.spec.containers[].name'"istio-proxy""native-tools-2"

可以發現這里存在一個 istio-proxy 的容器,也就是我們常說的 sidecar,這樣我們就可以把原本的 SDK 里的功能全部交給 Istio 去處理。gZZ28資訊網——每日最新資訊28at.com

總結

當然 Istio 的功能遠不止于此,比如:gZZ28資訊網——每日最新資訊28at.com

  • 統一網關,處理東西、南北向流量。
  • 灰度發布
  • 流量控制
  • 接口粒度的超時配置
  • 自動重試等

這次只是一個開胃菜,更多關于 Istio 的內容會在后續更新,比如會從如何在 kubernetes 集群中安裝 Istio 講起,帶大家一步步使用好 Istio。gZZ28資訊網——每日最新資訊28at.com

本文相關源碼:https://github.com/crossoverJie/k8s-combatgZZ28資訊網——每日最新資訊28at.com

參考鏈接:gZZ28資訊網——每日最新資訊28at.com

  • https://istio.io/latest/docs/setup/getting-started/
  • https://segmentfault.com/a/1190000042295402
  • https://go-zero.dev/docs/tutorials/service/governance/lb

本文鏈接:http://www.tebozhan.com/showinfo-26-13632-0.html在 Kubernetes 環境中實現 gRPC 負載均衡

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C++中的外部鏈接性和內部鏈接性:探究其區別與應用

下一篇: 一文徹底掌握MQ消息積壓全部解決方案

標簽:
  • 熱門焦點
  • 小米降噪藍牙耳機Necklace分享:聽一首歌 讀懂一個故事

    在今天下午的小米Civi 2新品發布會上,小米還帶來了一款新的降噪藍牙耳機Necklace,我們也在發布結束的第一時間給大家帶來這款耳機的簡單分享。現在大家能見到最多的藍牙耳機
  • vivo TWS Air開箱體驗:真輕 臻好聽

    在vivo S15系列新機的發布會上,vivo的最新款真無線藍牙耳機vivo TWS Air也一同發布,本次就這款耳機新品給大家帶來一個簡單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產
  • JavaScript 混淆及反混淆代碼工具

    介紹在我們開始學習反混淆之前,我們首先要了解一下代碼混淆。如果不了解代碼是如何混淆的,我們可能無法成功對代碼進行反混淆,尤其是使用自定義混淆器對其進行混淆時。什么是混
  • 三言兩語說透設計模式的藝術-單例模式

    寫在前面單例模式是一種常用的軟件設計模式,它所創建的對象只有一個實例,且該實例易于被外界訪問。單例對象由于只有一個實例,所以它可以方便地被系統中的其他對象共享,從而減少
  • JavaScript學習 -AES加密算法

    引言在當今數字化時代,前端應用程序扮演著重要角色,用戶的敏感數據經常在前端進行加密和解密操作。然而,這樣的操作在網絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數據
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • OPPO K11評測:旗艦級IMX890加持 2000元檔最強影像手機

    【Techweb評測】中端機型用戶群體巨大,占了中國目前手機市場的大頭,一直以來都是各手機品牌的“必爭之地”,其中OPPO K系列機型一直以來都以高品質、
  • 聯想的ThinkBook Plus下一版曝光,鍵盤旁邊塞個平板

    ThinkBook Plus 是聯想的一個特殊筆記本類別,它在封面放入了一塊墨水屏,也給人留下了較為深刻的印象。據有人爆料,聯想的下一款 ThinkBook Plus 可能更特殊,它
Top