package loadmodule import ( "bp.jydev.jianyu360.cn/BaseService/gateway/core/logs" "errors" "github.com/gogf/gf/v2/os/gctx" "net/url" "strconv" "strings" ) type WeightRoundRobinProxy struct { curIndex int rss []*WeightNode rsw []int } type WeightNode struct { addr *url.URL weight int //权重值 currentWeight int //节点当前权重 effectiveWeight int //有效权重 } func (r *WeightRoundRobinProxy) Add(param string) error { params := strings.Split(param, "|") if len(params) != 2 { return errors.New("param len need 2") } parInt, err := strconv.ParseInt(params[1], 10, 64) if err != nil { return err } remoteUrl, err := url.Parse(strings.TrimSpace(params[0])) if err != nil { return err } node := &WeightNode{addr: remoteUrl, weight: int(parInt)} node.effectiveWeight = node.weight r.rss = append(r.rss, node) return nil } func (r *WeightRoundRobinProxy) Next() *url.URL { if len(r.rss) == 1 { return r.rss[0].addr } total := 0 var best *WeightNode for i := 0; i < len(r.rss); i++ { w := r.rss[i] //step 1 统计所有有效权重之和 total += w.effectiveWeight //step 2 变更节点临时权重为的节点临时权重+节点有效权重 w.currentWeight += w.effectiveWeight //step 3 有效权重默认与权重相同,通讯异常时-1, 通讯成功+1,直到恢复到weight大小 if w.effectiveWeight < w.weight { w.effectiveWeight++ } //step 4 选择最大临时权重点节点 if best == nil || w.currentWeight > best.currentWeight { best = w } } if best == nil { logs.GInfo.Info(gctx.New(), "WeightRoundRobinProxy 获取权重异常 ") return r.rss[0].addr } //step 5 变更临时权重为 临时权重-有效权重之和 best.currentWeight -= total return best.addr } func (r *WeightRoundRobinProxy) Get() *url.URL { return r.Next() } func (r *WeightRoundRobinProxy) Len() int { return len(r.rss) } func (r *WeightRoundRobinProxy) Update() { }