登录
首页 >  Golang >  Go教程

Golang官方限流器库实现限流示例详解

来源:脚本之家

时间:2023-01-07 12:01:18 376浏览 收藏

IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《Golang官方限流器库实现限流示例详解》,聊聊限流、官方、限流器库,我们一起来看看吧!

令牌桶算法的原理是:令牌桶会不断地把令牌添加到桶里,而请求会从桶中获取令牌,只有拥有令牌地请求才能被接受。因为桶中可以提前保留一些令牌,所以它允许一定地突发流量通过。

例子

下面是限流算法常见的写法,首先判断是否有令牌,如果有就通过,否则直接失败。

package main
import (
	"fmt"
	"time"
	"golang.org/x/time/rate"
)
func main() {
        // 每0.1秒生成一个令牌,也就是一秒10个令牌,最大保留令牌上限10
	l := rate.NewLimiter(rate.Every(time.Second/10), 10)
	for i := 0; i 

上面的rate.Every(time.Second/10)会返回一个Limit类型,代表每秒生成多少个令牌。

这个库还提供了另外一种写法,等待直到有令牌为止(或超时):

func main() {
	l := rate.NewLimiter(rate.Every(time.Second/10), 100)
	for i := 0; i 

这样在某些场景下我们可以让请求等待一会,而不是直接失败。

还有一个更加特殊的请求令牌方式,也就是先预留令牌,到指定时间不再需要去获取令牌,直接执行操作即可:

func main() {
	l := rate.NewLimiter(rate.Every(time.Second/10), 10)
	for i := 0; i 

当然,如果预留的令牌不想使用了,也可以使用r.Cancel()归还已预留的令牌。

上面的Allow()、Wait()、Reserve()都是一次消耗一个令牌,其实都有对应的AllowN()、WaitN()、ReserveN()方法,一次消耗N个令牌,这样就可以根据任务消耗的资源灵活的消耗令牌。

实现

不管我们从Allow()、Wait()还是Reserve()进去,最终都会进入到reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation 方法:

首先在进入方法的时候,会先处理两种特殊情况:

        // 如果无限生成令牌,则直接返回
        if lim.limit == Inf {
		return Reservation{
			ok:        true,
			lim:       lim,
			tokens:    n,
			timeToAct: now,
		}
        // 如果不会生成令牌,则在初始令牌里面拿,直到拿完为止
	} else if lim.limit == 0 {
		var ok bool
		if lim.burst >= n {
			ok = true
			lim.burst -= n
		}
		return Reservation{
			ok:        ok,
			lim:       lim,
			tokens:    lim.burst,
			timeToAct: now,
		}
	}

然后重新计算当前有多少令牌,减去要消耗的令牌:

        // 计算当前有多少令牌
	now, last, tokens := lim.advance(now)
	// 减去要消耗的N个令牌
	tokens -= float64(n)
        // 如果剩余令牌为负数,那么计算一下要等待多久才能拿到令牌
        var waitDuration time.Duration
	if tokens 

余下的代码就是更新限流器的状态。

小结

可以看到这个令牌桶限流器实现的功能非常的丰富,如果需要令牌桶限流器,可以优先考虑使用这个实现。

好了,本文到此结束,带大家了解了《Golang官方限流器库实现限流示例详解》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表