限流算法之令牌桶

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

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

点赞