能自适应令牌生成速率的令牌桶实现

为了系统能够稳定的运行,我们常常会对请求进行限流,如果不进行限流的话,海量的请求很可能会把系统给压垮,丢弃部分请求来保证大部分的请求能正常响应往往是一个不错的选择

最常使用的限流方式就是令牌桶了,它的实现简单,可靠性高,只需要按照恒定的速率往令牌桶里面添加令牌,请求过来之后去令牌桶里面获取令牌,如果令牌为空则拒绝访问。

但是令牌桶比较难以使用,因为你很难确定流量限制为多少比较合适,太大的话系统承受不住,太小的话硬件性能得不到充分发挥,并且每台机器的硬件可能都不一致,你没办法把一套令牌桶参数放在不同的服务器上。即使你找到了合适的参数,但随着你系统版本的迭代更新,可能原先的参数就不是那么的合适了。找到一个合适的参数,往往是非常困难的。

我们可以用SmartRateLimiter来解决这个问题,它能根据你的硬件情况,自己找到一个合适的参数。

它会启动一个协程去监控硬件的CPU和内存的使用情况,如果CPU和内存的使用率超过警戒值,那么他会降低令牌的生成速率,减少进入系统的流量。如果CPU和内存的使用率过低并且真实请求速率大于令牌生成速率,则认为系统的工作是不饱和的,这时会加大令牌的生成速率,增加进入系统的流量,通过这种方式,能够根据机器的硬件情况,找到最合适的参数值。

ok,废话不多说,直接上代码

先看数据结构

type TokenBucket struct {
   
	Capacity          int64        //令牌桶容量  可以缓存部分令牌
	Ch                chan bool    //令牌桶
	CountPerSecond    int64        //每秒生成令牌数
	AddTimer          *time.Ticker //增加令牌的定时器
	RealPerSecond     int64        //实际上每秒的请求量
	Counter           int64        //计数器
	RealPerSenconds   *Queue       //缓存每秒请求量的队列
	ResetCounterTimer *time.Ticker //重置计数器的定时器
	UpdateTimer       *time.Ticker //更新生成令牌速率的定时器
	CpuPercent        float64      //cpu使用率的预警值
	MemPercent        float64      //内存使用率的预警值
}

创建一个令牌桶

func NewTokenBucket(capacity int64, countPerSecond int64, cpuPercent float64, memPercent float64) *TokenBucket {
   
	tokenBucket := &TokenBucket{
   
		Capacity:          capacity,
		Ch:                make(chan bool, capacity),
		CountPerSecond:    countPerSecond,
		AddTimer:          time.NewTicker(time.Duration(int64(time.Second) / countPerSecond)),
		RealPerSenconds:   &Queue{
   
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值