Golang實現(xiàn)按比例切分流量的示例詳解
我們在進行灰度發(fā)布時,往往需要轉(zhuǎn)發(fā)一部分流量到新上線的服務(wù)上,進行小規(guī)模的驗證,隨著功能的不斷完善,我們也會逐漸增加轉(zhuǎn)發(fā)的流量,這就需要按比例去切分流量,那么如何實現(xiàn)流量切分呢?
我們很容易想到通過生成隨機數(shù)方式進行實現(xiàn),通過判斷生成隨機數(shù)是否落在指定區(qū)間內(nèi),從而決定是否進行流量的轉(zhuǎn)發(fā),這種方式雖然實現(xiàn)很簡單,但是它有兩點弊端:
- 每次都要生成新的隨機數(shù),這是有性能損耗的,尤其是并發(fā)量高的場景下更為明顯;
- 隨機數(shù)的生成往往不夠均勻,比如有A、B兩個服務(wù),流量比例3:7,如果使用隨機數(shù)方式,如果運氣不好的話有可能請求100次全落在B服務(wù)上。
那有沒有性能開銷又小,又能精準切分流量的方式呢?當(dāng)然是有的。實現(xiàn)思路如下:
- 確定比例,并根據(jù)比例得到一個基數(shù)base,例如比例是3:7,那么基數(shù)就是10;
- 生成長度為基數(shù)base的數(shù)組source,并填充數(shù)據(jù)0、1、2、3、4、5...;
- 打亂數(shù)組source中元素順序;
- 創(chuàng)建全局計數(shù)器queryCount,每次有請求時加1(確保原子性);
- 計算計數(shù)器queryCount與base取余后的值rate,并得到數(shù)組中對應(yīng)位置的值source[rate];
- 判斷source[rate]落在哪個區(qū)間。
看文字可能覺得理解起來有些別扭,這里貼上完整代碼:
import ( "fmt" "math/rand" "sync/atomic") type TrafficControl struct { source []int queryCount uint32 base int ratio int } func NewTrafficControl(base int, ratio int) *TrafficControl { source := make([]int, base) for i := 0; i < base; i++ { source[i] = i } rand.Shuffle(base, func(i, j int) { source[i], source[j] = source[j], source[i] }) return &TrafficControl{ source: source, base: base, ratio: ratio, } } func (t *TrafficControl) Allow() bool { rate := t.source[int(atomic.AddUint32(&t.queryCount, 1))%t.base] if rate < t.ratio { return true } else { return false } }
接下來我們檢測下這段代碼是否真的能精準切分流量:
func main() { trafficCtl := NewTrafficControl(10, 6) cnt := 100 serviceAQueryCnt := 0 serviceBQueryCnt := 0 for cnt > 0 { if trafficCtl.Allow() { serviceAQueryCnt++ } else { serviceBQueryCnt++ } cnt-- } fmt.Printf("service A query count: %v, service B query count %v", serviceAQueryCnt, serviceBQueryCnt) }
執(zhí)行結(jié)果如下:
service A query count: 60, service B query count 40
其實思路很簡單:通過請求數(shù)與基數(shù)取余,確保在一定范圍內(nèi)總能按比例 實現(xiàn)流量切分;通過打亂數(shù)組確保流量分布盡可能均勻。當(dāng)然流量切分還有其他實現(xiàn)方式,如果大家有更精妙的實現(xiàn),歡迎評論區(qū)留言哈。
到此這篇關(guān)于Golang實現(xiàn)按比例切分流量的示例詳解的文章就介紹到這了,更多相關(guān)Golang按比例切分流量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言中函數(shù)可變參數(shù)(Variadic Parameter)詳解
在Python中,在函數(shù)參數(shù)不確定數(shù)量的情況下,可以動態(tài)在函數(shù)內(nèi)獲取參數(shù)。在Go語言中,也有類似的實現(xiàn)方式,本文就來為大家詳細講解一下2022-07-07Go語言數(shù)據(jù)結(jié)構(gòu)之二叉樹必會知識點總結(jié)
如果你是一個開發(fā)人員,或多或少對樹型結(jié)構(gòu)都有一定的認識。二叉樹作為樹的一種,是一種重要的數(shù)據(jù)結(jié)構(gòu),也是面試官經(jīng)常考的東西。本文為大家總結(jié)了一些二叉樹必會知識點,需要的可以參考一下2022-08-08