微服务,API限流(三)

简介

常用的限流算法有两种:漏桶算法和令牌桶算法。

漏桶算法

漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
在这里插入图片描述

令牌桶算法

对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如下图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
在这里插入图片描述
以上内容来自网络,指望我写简介,※=○☆(__*)Zzz

go自带令牌桶rate

标准包如下,自行科学上网获取,或者去国内代理下载

"golang.org/x/time/rate"

创建实例

//参数Limit,生成令牌速率,每秒多少个,参数b:桶最大容量
limiter := rate.NewLimiter(1,5)

使用方法

三个方法中,推荐使用wait方法


//WaitN 函数,等待获取令牌,这里设置最大等待时长2s
//如果在最大等待时长内无法获取,则直接跳出,不会进行等待
//Wait函数等价于WaitN(ctx,1)
ctx,_:= context.WithTimeout(context.Background(),time.Second*2)
err := limiter.WaitN(ctx,2)

//AllowN 当没有可用或足够的事件时,返回false
//Allow函数等同于AllowN(time.Now(),1)
limiter.AllowN(time.Now(),2)

//ReserveN 返回对象Reservation ,标识调用者需要等多久才能等到n个事件发生(意思就是等多久令牌池中至少含有n个令牌)。
//Reserve函数等价于ReserveN(time.Now(),1)
limiter.ReserveN(time.Now(),2)

实战使用

这里结合gin框架使用,将限流服务当做gin的一个中间件
至于如何将gin和go-kit搭配使用,以后会出文章详解

var limiter * rate.Limiter

func init(){
	limiter = rate.NewLimiter(100,1024)
}
func RateLimiter(c *gin.Context){
	ctx,_:=context.WithTimeout(context.Background(),time.Second*10)
	if err := limiter.Wait(ctx);err==nil{
		c.Next()
	}else {
		c.String(503 ,"系统繁忙,请稍后重试:"+err.Error())
		c.Abort()
	}
}

将这个中间件注册到gin服务服务中,此时,基于令牌桶的限流功能就做好了。

g.Use(middle.RateLimiter)

猜你喜欢

转载自blog.csdn.net/qq_25490573/article/details/106823801