当前位置:首页 > 编程笔记 > 正文
已解决

golang官方限流器rate

来自网友在路上 167867提问 提问时间:2023-09-26 20:25:12阅读次数: 67

最佳答案 问答题库678位专家为你答疑解惑

包名:golang.org/x/time/rate

实现原理:令牌桶

package mainimport ("context""fmt""testing""time""golang.org/x/time/rate"
)func TestLimiter(t *testing.T) {// 每秒生产一个令牌,桶里最多有10个令牌l := rate.NewLimiter(rate.Every(time.Second), 10)for i := 0; i < 10; i++ {go func(i int) {for {if l.Allow() {fmt.Printf("allow %d\n", i)}// 每0.5秒请求一次time.Sleep(time.Second / 2)}}(i)}time.Sleep(time.Second * 10)
}func TestLimiter2(t *testing.T) {l := rate.NewLimiter(rate.Every(time.Second), 10)for i := 0; i < 10; i++ {go func(i int) {for {ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(1*time.Second))// 等待获取令牌,可以传入 deadline context 设置最大等待时间// 这样在某些场景下我们可以让请求等待一会,而不是直接失败。if err := l.Wait(ctx); err != nil {fmt.Printf("timwout: %v\n", err)} else {fmt.Printf("allow %d\n", i)}cancel()time.Sleep(time.Second / 2)}}(i)}time.Sleep(time.Second * 10)
}func TestLimiter3(t *testing.T) {l := rate.NewLimiter(rate.Every(time.Second), 10)for i := 0; i < 10; i++ {go func(i int) {for {// 先预留令牌,到指定时间不再需要去获取令牌,直接执行操作// 如果预留的令牌不想使用了,也可以使用r.Cancel()归还已预留的令牌if r := l.Reserve(); r.OK() {// 休眠直到令牌生效time.Sleep(r.Delay())fmt.Printf("allow %d\n", i)}time.Sleep(time.Second / 2)}}(i)}time.Sleep(time.Second * 10)
}
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"golang官方限流器rate":http://eshow365.cn/6-14150-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!