grpc负载均衡RoundRobin源码解读

grpc client端创建连接时可以用WithBalancer来指定负载均衡组件,这里研究下grpc自带的RoundRobin(轮询调度)的实现。源码在google.golang.org/grpc/balancer.go中。

roundRobin结构体定义如下:

type roundRobin struct {
	r      naming.Resolver
	w      naming.Watcher
	addrs  []*addrInfo // all the addresses the client should potentially connect
	mu     sync.Mutex
	addrCh chan []Address // the channel to notify gRPC internals the list of addresses the client should connect to.
	next   int            // index of the next address to return for Get()
	waitCh chan struct{}  // the channel to block when there is no connected address available
	done   bool           // The Balancer is closed.
}
  • r是命名解析器,可以定义自己的命名解析器,如etcd命名解析器。如果r为nil,那么Dial中参数target将直接作为可请求地址添加到addrs中。
  • w是命名解析器Resolve方法返回的watcher,该watcher可以监听命名解析器发来的地址信息变化,通知roundRobin对addrs中的地址进行动态的增删。
  • addrs是从命名解析器获取地址信息数组,数组中每个地址不仅有地址信息,还有grpc与该地址是否已经创建了ready状态的连接。
  • addrCh是地址数组的channel,该channel会在每次命名解析器发来地址信息变化后,将所有addrs通知到grpc内部的lbWatcher,lbWatcher是统一管理地址连接状态的协程,负责新地址的连接与被删除地址的关闭操作。
  • next是roundRobin的Index,即轮询调度遍历到addrs数组中的哪个位置了。
  • waitCh是当addrs中地址为空时,grpc调用Get()方法希望获取到一个到target的连接,如果设置了grpc的failfast为false,那么Get()方法会阻塞在此channel上,直到有ready的连接。

roundRobin启动:

func (rr *roundRobin) Start(target string, config BalancerConfig) error {
	rr.mu.Lock()
	defer rr.mu.Unlock()
	if rr.done {
		return ErrClientConnClosing
	}
	if rr.r == nil {
		// 如果没有解析器,那么直接将target加入addrs地址数组
		rr.addrs = append(rr.addrs, &addrInfo{addr: Address{Addr: target}})
		return nil
	}
	// Resolve接口会返回一个watcher,watcher可以监听解析器的地址变化
	w, err := rr.r.Resolve(target)
	if err != nil {
		return err
	}
	rr.w = w
	// 创建一个channel,当watcher监听到地址变化时,通知grpc内部lbWatcher去连接该地址
	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值