The usage of ConsistentHashLoadBalance in dubbo-go
This article introduces the knowledge of "the use of ConsistentHashLoadBalance in dubbo-go". Many people will encounter such a dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Order
This paper mainly studies the ConsistentHashLoadBalance of dubbo-go.
ConsistentHashLoadBalance
Dubbo-go-v1.4.2/cluster/loadbalance/consistent_hash.go
Const (/ / ConsistentHash... ConsistentHash = "consistenthash" / / HashNodes. HashNodes = "hash.nodes" / / HashArguments. HashArguments = "hash.arguments") var (selectors = make (map [string] * ConsistentHashSelector) re = regexp.MustCompile (constant.COMMA_SPLIT_PATTERN)) func init () {extension.SetLoadbalance (ConsistentHash, NewConsistentHashLoadBalance)} / / ConsistentHashLoadBalance. Type ConsistentHashLoadBalance struct {} / / NewConsistentHashLoadBalance. Func NewConsistentHashLoadBalance () cluster.LoadBalance {return & ConsistentHashLoadBalance {}}
The init method of ConsistentHashLoadBalance sets the ConsistentHashLoadBalance named consistenthash to the extension
Select
Dubbo-go-v1.4.2/cluster/loadbalance/consistent_hash.go
/ / Select... func (lb * ConsistentHashLoadBalance) Select (invokers [] protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {methodName: = invocation.MethodName () key: = invokers [0] .GetUrl (). ServiceKey () + "." + methodName / / hash the invokers bs: = make ([] byte, 0) for _, invoker: = range invokers {b Err: = json.Marshal (invoker) if err! = nil {return nil} bs = append (bs, b...)} hashCode: = crc32.ChecksumIEEE (bs) selector, ok: = selectors [key] if! ok | | selector.hashCode! = hashCode {selectors [key] = newConsistentHashSelector (invokers, methodName) HashCode) selector = selectors [key]} return selector.Select (invocation)}
The Select method traverses the invokers and executes json.Marshal (invoker) one by one, adds bytes [] to the bs, then calculates the hashCode through crc32.ChecksumIEEE (bs), then compares whether the hashCode of selectors [key] is consistent with the calculated hashCode, resets one through newConsistentHashSelector, and finally executes selector.Select (invocation).
ConsistentHashSelector
Dubbo-go-v1.4.2/cluster/loadbalance/consistent_hash.go
/ / ConsistentHashSelector... type ConsistentHashSelector struct {hashCode uint32 replicaNum int virtualInvokers map[uint32] protocol.Invoker keys Uint32Slice argumentIndex [] int}
ConsistentHashSelector defines hashCode, replicaNum, virtualInvokers, keys, argumentIndex attributes
NewConsistentHashSelector
Dubbo-go-v1.4.2/cluster/loadbalance/consistent_hash.go
Func newConsistentHashSelector (invokers [] protocol.Invoker, methodName string, hashCode uint32) * ConsistentHashSelector {selector: = & ConsistentHashSelector {} selector.virtualInvokers = make (map [uint32] protocol.Invoker) selector.hashCode = hashCode url: = invokers [0] .GetUrl () selector.replicaNum = int (url.GetMethodParamInt (methodName, HashNodes, 160) indices: = re.Split (url.GetMethodParam (methodName, HashArguments, "0") -1) for _, index: = range indices {I, err: = strconv.Atoi (index) if err! = nil {return nil} selector.argumentIndex = append (selector.argumentIndex, I)} for _ Invoker: = range invokers {u: = invoker.GetUrl () address: = u.Ip + ":" + u.Port for I: = 0 I
< selector.replicaNum/4; i++ { digest := md5.Sum([]byte(address + strconv.Itoa(i))) for j := 0; j < 4; j++ { key := selector.hash(digest, j) selector.keys = append(selector.keys, key) selector.virtualInvokers[key] = invoker } } } sort.Sort(selector.keys) return selector} newConsistentHashSelector方法实例化ConsistentHashSelector,并初始化virtualInvokers、hashCode、argumentIndex、keys、virtualInvokers属性 Select dubbo-go-v1.4.2/cluster/loadbalance/consistent_hash.go // Select ...func (c *ConsistentHashSelector) Select(invocation protocol.Invocation) protocol.Invoker { key := c.toKey(invocation.Arguments()) digest := md5.Sum([]byte(key)) return c.selectForKey(c.hash(digest, 0))}func (c *ConsistentHashSelector) toKey(args []interface{}) string { var sb strings.Builder for i := range c.argumentIndex { if i >= 0 & & I
< len(args) { fmt.Fprint(&sb, args[i].(string)) } } return sb.String()}func (c *ConsistentHashSelector) selectForKey(hash uint32) protocol.Invoker { idx := sort.Search(len(c.keys), func(i int) bool { return c.keys[i] >= hash}) if idx = = len (c.keys) {idx = 0} return c.virtualInvokers [c.keys [IDX]]} func (c * ConsistentHashSelector) hash (digest [16] byte, I int) uint32 {return uint32 ((digest [3 + iTunes 4] & 0xFF)