1. 程式人生 > >限流演算法之令牌桶

限流演算法之令牌桶

一、令牌桶演算法和漏桶演算法

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")
}