? 背景
后端兩個(gè)服務(wù) ServiceA蝠咆、ServiceB,ServiceA 通過(guò) gRPC 遠(yuǎn)程調(diào)用 ServiceB辨液。在 Docker Swarm 集群下每個(gè)服務(wù)部署多個(gè)副本吐咳,假設(shè)部署兩個(gè)副本,即 ServiceA 的實(shí)例為 A1 和 A2俏站,ServiceB 的實(shí)例為 B1 和 B2。Swarm 集群內(nèi)部通過(guò) Overlay 網(wǎng)絡(luò)實(shí)現(xiàn)容器間通信痊土,ServiceA 訪問(wèn) ServiceB 通過(guò)服務(wù)名稱(chēng)來(lái)連接肄扎,即 A1 調(diào)用 ServiceB 時(shí),會(huì)隨機(jī)調(diào)用到 B1 或者 B2;同理犯祠,A2 也是如此旭等。
上述流程,看似合理且正常衡载,然而實(shí)際效果是:假設(shè) A1 連通 B1搔耕,A2 連通 B1,那么 ServiceA 的請(qǐng)求會(huì)一直被 B1 接收并處理痰娱,直至 TCP 連接超時(shí)弃榨,或者 B1 服務(wù)終止。gRPC 的核心概念中有 Channel 梨睁,描述 Client 與 Server 之間的連接鲸睛,即 A1 與 B1 建立連接之后, Channel 會(huì)被復(fù)用坡贺。
面對(duì)這種負(fù)載不均衡的場(chǎng)景官辈,我們希望 ServiceA 的每個(gè)請(qǐng)求能被均衡到 ServiceB 的每個(gè)實(shí)例去處理。
? GRPC 負(fù)載均衡
工作流程
- 1遍坟、Client 請(qǐng)求解析 server name钧萍,獲取一個(gè)或多個(gè)實(shí)際 IP 地址,例如 ServiceB 解析為 10.0.0.10政鼠、10.0.0.11
- 2风瘦、Client 實(shí)例化負(fù)載均衡策略,可選策略為
round_robin
和grpclb
公般。注意:如果解析程序返回的地址是均衡器地址万搔,無(wú)論 Client 配置什么負(fù)載均衡策略,都將使用grpclb
策略官帘。否則瞬雹,會(huì)使用 Client 配置的負(fù)載均衡策略。如果未配置刽虹,則 Client 將默認(rèn)選用第一個(gè)可用服務(wù)器地址的策略 - 3酗捌、負(fù)載均衡衡策略為每個(gè)服務(wù)器地址創(chuàng)建一個(gè)子通道
- 4、對(duì)于每個(gè) RPC 請(qǐng)求涌哲,負(fù)載均衡策略決定應(yīng)將 RPC 請(qǐng)求發(fā)送到哪個(gè)子通道(即哪個(gè)服務(wù)器)
針對(duì)上述場(chǎng)景胖缤,在 Swarm 集群中,我們應(yīng)該選擇 dnsrr
模式阀圾,并且 gRPC 客戶端配置負(fù)載均衡策略為 round_robin
(輪訓(xùn))即可哪廓。
? 配置 Load Balance Policy
不同語(yǔ)言配置方式不同,以下列舉常用語(yǔ)言:
grpc-java 配置
ManagedChannel channel = ManagedChannelBuilder.forAddress(server.getHost(), server.getPort())
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext().build();
其他語(yǔ)言
有待完善初烘。涡真。分俯。
配置 Docker Swarm dnsrr
Docker Swarm 默認(rèn)的模式是 vip
,使用 dnsrr
只需將 endpoint_mode
設(shè)置為 dnsrr
即可哆料,相關(guān)資料:
示例:
version: '3.7'
services:
server:
image: "server:latest"
stop_grace_period: 20s
networks:
- idp_network
deploy:
replicas: 2
endpoint_mode: dnsrr
networks:
idp_network:
external: true
Spring Boot gRPC Load Balance 案例
1缸剪、獲取案例源碼
git clone https://github.com/ChinaSilence/spring-boot-starter-grpc.git
2、Install 相關(guān)包
- https://github.com/ChinaSilence/spring-boot-starter-grpc/tree/master/spring-boot-starter-grpc
- https://github.com/ChinaSilence/spring-boot-starter-grpc/tree/master/samples-facade
3东亦、構(gòu)建相關(guān)鏡像
- server: https://github.com/ChinaSilence/spring-boot-starter-grpc/tree/master/samples-server
- client: https://github.com/ChinaSilence/spring-boot-starter-grpc/tree/master/samples-client
4橄登、初始化 Swarm 集群
docker swarm init
5、添加 Overlay 網(wǎng)絡(luò)
docker network create -d overlay --attachable idp_network
6讥此、部署 gRPC server 和 client
docker stack deploy -c stack.yml grpc
在 stack.yml
文件所在路徑下執(zhí)行
7、查看 server 端日志
docker service logs -f grpc_server
8谣妻、持續(xù)通過(guò) client 發(fā)送請(qǐng)求萄喳,并觀察日志信息
curl http://localhost:8081/v1/user/list
從日志中可以看出,server 能均衡處理 client 的請(qǐng)求蹋半。