Kitex 負載均衡擴展

2022-04-27 10:29 更新

負載均衡擴展

在 Kitex 中,提供了兩種 LoadBalancer:

  1. WeightedRandom
  2. ConsistentHash

這兩種 LoadBalancer 能覆蓋絕大多數(shù)的應(yīng)用場景,如果業(yè)務(wù)有一些 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 并且生成一個針對當(dāng)次請求的 Picker,Picker 定義如下:

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

有可能在一次的 rpc 請求中,所選擇的實例連接不上,而要進行重試,所以設(shè)計成這樣。

如果說已經(jīng)沒有實例可以重試了,Next 方法應(yīng)當(dāng)返回 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,務(wù)必實現(xiàn) Rebalancer 接口,否則服務(wù)發(fā)現(xiàn)變更就無法被通知到了。

Kitex client 會在初始化的時候執(zhí)行以下代碼來保證當(dāng)服務(wù)發(fā)現(xiàn)變更時,能通知到 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)
    })
}

注意事項

如果是動態(tài)服務(wù)發(fā)現(xiàn),那么盡可能實現(xiàn)緩存,可以提高性能;

如果使用了緩存,那么務(wù)必實現(xiàn) Rebalancer 接口,否則當(dāng)服務(wù)發(fā)現(xiàn)變更時無法收到通知;

使用了 Proxy 場景下,不支持自定義 LoadBalancer。

Example

可以參考一下 Kitex 默認的 WeightedRandom 實現(xiàn)。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號