Golang加權(quán)輪詢負(fù)載均衡的實(shí)現(xiàn)
實(shí)現(xiàn)加權(quán)輪詢負(fù)載均衡思路
代碼實(shí)現(xiàn)一個(gè)加權(quán)負(fù)載均衡
- Weight 初始化時(shí)對(duì)節(jié)點(diǎn)約定的權(quán)重
- currentWeight 節(jié)點(diǎn)臨時(shí)權(quán)重,每輪都會(huì)變化
- effectiveWeight 節(jié)點(diǎn)有效權(quán)重,默認(rèn)與Weight相同
- totalWeight 所有節(jié)點(diǎn)有效權(quán)重之和:sum(effectiveWeight)
代碼實(shí)現(xiàn)一個(gè)加權(quán)負(fù)載均衡
- currentWeight = currentWeight+effecitveWeight
- 選中最大的 currentWeight 節(jié)點(diǎn)為選中節(jié)點(diǎn)
- currentWeight = currentWeight-totalWeight (4+3+2=9)
所以我們能夠 在表格模擬運(yùn)行情況:
請求次數(shù) | 請求前currentWelght | 選中的節(jié)點(diǎn) | 請求后currentWelght |
---|---|---|---|
1 | [serverA=4,serverB=3,serverC=2] | serverA | [serverA=-1,serverB=6,serverC=4] |
2 | [serverA=-1,serverB=6,serverC=4] | serverB | [serverA=3,serverB=0,serverC=6] |
3 | [serverA=3,serverB=0,serverC=6] | serverc | [serverA=7,serverB=3,serverC=-1] |
4 | [serverA=7,serverB=3,serverC=-1] | serverA | [serverA=2,serverB=6,serverC=1] |
5 | [serverA=2,serverB=6,serverC=1] | serverB | [serverA=6,serverB=0,serverC=3] |
6 | [serverA=6,serverB=0,serverC=3] | serverA | [serverA=1,serverB=3,serverC=5] |
7 | [serverA=1,serverB=3,serverC=5] | serverc | [serverA=5,serverB=6,serverC=-2] |
加權(quán)輪詢負(fù)載均衡代碼
package load_balance import ( "errors" "strconv" ) type WeightRoundRobinBalance struct { curIndex int rss []*WeightNode rsw []int //觀察主體 conf LoadBalanceConf } // 配置主題 type LoadBalanceConf interface { GetConf() []string WatchConf() UpdateConf(conf []string) } type WeightNode struct { addr string // 服務(wù)器地址 weight int //權(quán)重值 currentWeight int //節(jié)點(diǎn)當(dāng)前權(quán)重 effectiveWeight int //有效權(quán)重 } func (r *WeightRoundRobinBalance) Add(params ...string) error { if len(params) != 2 { return errors.New("param len need 2") } parInt, err := strconv.ParseInt(params[1], 10, 64) if err != nil { return err } node := &WeightNode{addr: params[0], weight: int(parInt)} node.effectiveWeight = node.weight r.rss = append(r.rss, node) return nil } func (r *WeightRoundRobinBalance) Next() string { total := 0 var best *WeightNode for i := 0; i < len(r.rss); i++ { w := r.rss[i] //step 1 統(tǒng)計(jì)所有有效權(quán)重之和 total += w.effectiveWeight //step 2 變更節(jié)點(diǎn)臨時(shí)權(quán)重為的節(jié)點(diǎn)臨時(shí)權(quán)重+節(jié)點(diǎn)有效權(quán)重 w.currentWeight += w.effectiveWeight //step 3 有效權(quán)重默認(rèn)與權(quán)重相同,通訊異常時(shí)-1, 通訊成功+1,直到恢復(fù)到weight大小 if w.effectiveWeight < w.weight { w.effectiveWeight++ } //step 4 選擇最大臨時(shí)權(quán)重點(diǎn)節(jié)點(diǎn) if best == nil || w.currentWeight > best.currentWeight { best = w } } if best == nil { return "" } //step 5 變更臨時(shí)權(quán)重為 臨時(shí)權(quán)重-有效權(quán)重之和 best.currentWeight -= total return best.addr } func (r *WeightRoundRobinBalance) Get(key string) (string, error) { return r.Next(), nil } func (r *WeightRoundRobinBalance) SetConf(conf LoadBalanceConf) { r.conf = conf }
測試代碼
package load_balance import ( "fmt" "testing" ) func TestLB(t *testing.T) { rb := &WeightRoundRobinBalance{} rb.Add("127.0.0.1:2003", "4") //0 // rb.Add("127.0.0.1:2004", "3") //1 rb.Add("127.0.0.1:2005", "2") //2 fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) }
測試結(jié)果
$ go test
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
PASS
ok gateway/_test/demo 0.080s## 127.0.0.1:2003 為 127.0.0.1:2005 權(quán)重兩倍。而從答應(yīng)結(jié)果上看,符合要求
到此這篇關(guān)于Golang加權(quán)輪詢負(fù)載均衡的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Golang加權(quán)輪詢負(fù)載均衡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言切片slice使用細(xì)節(jié)和注意事項(xiàng)整理大全
這篇文章主要給大家介紹了關(guān)于go語言切片slice使用細(xì)節(jié)和注意事項(xiàng)整理的相關(guān)資料,需要的朋友可以參考下2024-05-05Go語言中函數(shù)可變參數(shù)(Variadic Parameter)詳解
在Python中,在函數(shù)參數(shù)不確定數(shù)量的情況下,可以動(dòng)態(tài)在函數(shù)內(nèi)獲取參數(shù)。在Go語言中,也有類似的實(shí)現(xiàn)方式,本文就來為大家詳細(xì)講解一下2022-07-07