codecamp

Kitex 负载均衡扩展

负载均衡扩展

在 Kitex 中,提供了两种 LoadBalancer:

  1. WeightedRandom
  2. ConsistentHash

这两种 LoadBalancer 能覆盖绝大多数的应用场景,如果业务有一些 Corner Case 无法覆盖到,可以选择自己自定义 LoadBalancer。

接口 

LoadBalancer 接口在 ​pkg/loadbalance/loadbalancer.go​ 中,具体定义如下:

// Loadbalancer generates pickers for the given service discovery result.
type Loadbalancer interface {
    GetPicker(discovery.Result) Picker
    // 名称需要唯一
    Name() string
}

可以看到 LoadBalancer 获取到一个 Result 并且生成一个针对当次请求的 Picker,Picker 定义如下:

// Picker picks an instance for next RPC call.
type Picker interface {
    Next(ctx context.Context, request interface{}) discovery.Instance
}

有可能在一次的 rpc 请求中,所选择的实例连接不上,而要进行重试,所以设计成这样。

如果说已经没有实例可以重试了,Next 方法应当返回 nil。

除了以上接口之外,还有一个比较特殊的接口,定义如下:

// Rebalancer is a kind of Loadbalancer that performs rebalancing when the result of service discovery changes.
type Rebalancer interface {
    Rebalance(discovery.Change)
    Delete(discovery.Change)
}

如果 LoadBalancer 支持 Cache,务必实现 Rebalancer 接口,否则服务发现变更就无法被通知到了。

Kitex client 会在初始化的时候执行以下代码来保证当服务发现变更时,能通知到 Rebalancer:

if rlb, ok := balancer.(loadbalance.Rebalancer); ok && bus != nil {
    bus.Watch(discovery.DiscoveryChangeEventName, func(e *event.Event) {
        change := e.Extra.(*discovery.Change)
        rlb.Rebalance(*change)
    })
}

注意事项

如果是动态服务发现,那么尽可能实现缓存,可以提高性能;

如果使用了缓存,那么务必实现 Rebalancer 接口,否则当服务发现变更时无法收到通知;

使用了 Proxy 场景下,不支持自定义 LoadBalancer。

Example

可以参考一下 Kitex 默认的 WeightedRandom 实现。


Kitex 服务发现扩展
Kitex 监控扩展
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }