golang令牌桶实现 [go-rate] 速率限制器


当前第2页 返回上一页

使用一个伪代码来举例,我们可以如何使用 Reserve 方法。

r := lim.Reserve()
//是否愿意等待
f !r.OK() {
    //不愿意等待直接退出
    return
}

//如果愿意等待,将等待时间抛给用户 time.Sleep代表用户需要等待的时间。
time.Sleep(r.Delay())
Act() // 一段时间后生成生成新的令牌,开始执行相关逻辑

动态调整速率

Limiter 支持可以调整速率和桶大小:

  1. SetLimit(Limit) 改变放入 Token 的速率
  2. SetBurst(int) 改变 Token 桶大小

有了这两个方法,可以根据现有环境和条件以及我们的需求,动态地改变 Token 桶大小和速率。

案例1-单位时间只允许一次邮件发送操作

客户端软件客户点击发送邮件,如果客户一秒钟内点击10次,就会发送10次,这明显是不合适的。如果使用速率限制,我们就可以限制一秒内只能发送一次,实现方法为:

(令牌桶)容量为1,速度为每一秒生成一个令牌,这样可以保证一秒钟只会被执行一次,伪代码实现如下

//初始化 limiter 每秒生成1个令牌,令牌桶容量为20
limiter := rate.NewLimiter(rate.Every(time.Second), 1)
//模拟单位时间执行多次操作
for i := 0; i < 5; i++ {
    if limiter.Allow() {
        fmt.Println("发送邮件")
    } else {
        fmt.Println("请求多次,过滤")
    }
}
if limiter.Allow() {
        fmt.Println("发送邮件")
}

执行结果

发送邮件
请求多次,过滤
请求多次,过滤
请求多次,过滤
请求多次,过滤
发送邮件

我们发现,第一次执行是可以被允许的因为第一次的令牌被允许,之后的请求失败是因为还没有生成新的令牌,所以需要等待1秒,之后又可以进行发送邮件操作。

通过这样一个案例,相信大家对令牌桶的实现场景有了一个基本的了解。

案例2——令牌取出单个和多个

初始化令牌桶容量为20,设置每100毫秒生成一个令牌,即1秒生产10个令牌。编码测试功能

//初始化 limiter 每秒10个令牌,令牌桶容量为20
limiter := rate.NewLimiter(rate.Every(time.Millisecond*100), 20)
for i := 0; i < 25; i++ {
    if limiter.Allow() {
        fmt.Println("success") //do something
    } else {
        fmt.Println("busy")
    }
}

//阻塞直到获取足够的令牌或者上下文取消
ctx, _ := context.WithTimeout(context.Background(), time.Second*2)
fmt.Println("start get token", time.Now())
err := limiter.WaitN(ctx, 20)
if err != nil {
    fmt.Println("error", err)
    return
}
fmt.Println("success get token", time.Now())

第二段编码阻塞的场景在于,一次性取出20个令牌给予2秒的等待时间,如果有20个令牌可以取出打印成功消息,如果2秒等待时间内没有20个令牌可以取出,程序直接退出,即失败。

参考

我的博客|文章首发

go-rate

Golang 标准库限流器 time/rate 使用介绍

Golang限流器rate使用

END

欢迎关注公众号 程序员工具集 致力于分享优秀的开源项目、学习资源 、常用工具

回复关键词“关注礼包”,送你一份最全的程序员技能图谱。


本文来自:51CTO博客

感谢作者:qq5c5012ac9b084

查看原文:golang令牌桶实现 [go-rate] 速率限制器

返回前面的内容

相关阅读 >>

Golang中定义不定长数组的方法

Golang map 不排序怎么办

最清晰易懂的 Go waitgroup 源码剖析

docker为何选择Golang开发?

堆排序

Golang有什么用途?

Go入门-1 变量

Golang flag是什么

Go语言学习(三):源码文件

Go select

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...