限流演算法之令牌桶
阿新 • • 發佈:2019-01-31
一、令牌桶演算法和漏桶演算法
1、漏桶演算法,有一個固定大小的桶,桶中的流量按照固定的速率流出,此時若有流量流入桶中,如果流入的速率比流出的速率大,則可能導致超過桶大小的流量溢位。
2、令牌演算法,有一個固定大小的桶,按照一定的速率往桶中放入令牌,如果令牌超過桶大小則會溢位,此時若有流量需要傳送,則先到令牌桶取傳送的數目(如果數目不足則等待一段時間再取),令牌桶的數目相應的減少。
區別:漏桶演算法只允許按照一定的速率傳送,而令牌桶根據令牌數目來發送,最大可允許傳送桶大小的流量。
二、令牌桶測試(golang)
package main import ( "fmt" "time" ) //桶容量 var capacity int64 = 256 * 1024 * 1024 //令牌放入的速度 var rate int64 = 128 * 1024 * 1024 //當前令牌數量 var tokens int64 = 0 var timestamp time.Time = time.Now() func min(va, vb int64) int64 { if va <= vb { return va } return vb } func grant(packetsize int64) bool { if packetsize > capacity || packetsize < 1 { return false } now := time.Now() //獲取令牌桶的令牌數量---如果生成的令牌數量多於桶容量,則溢位 tokens = min(capacity, tokens+(now.Unix()-timestamp.Unix())*rate) timestamp = now if tokens < packetsize { return false } else { tokens -= packetsize return true } } func main() { if ret := grant(1024 * 1024 * 128); ret { fmt.Println("trans packet at first") return } select { case <-time.After(time.Second): break } if ret := grant(1024 * 1024 * 128); ret { fmt.Println("trans packet at second") return } fmt.Println("No trans") }