
在高并发的系统中,限流已作为必不可少的功能,而常见的限流算法有:计数器、滑动窗口、令牌桶、漏斗(漏桶)。其中滑动窗口算法、令牌桶和漏斗算法应用最为广泛。
这里不再对计数器算法和滑动窗口作介绍了,有兴趣的同学可以参考其它相关文章。
非常很好理解,就像有一个漏斗容器一样,漏斗上面一直往容器里倒水(请求),漏斗下方以 固定速率 一直流出(消费)。如果漏斗容器满的情况下,再倒入的水就会溢出,此时表示新的请求将被丢弃。可以看到这种算法在应对大的突发流量时,会造成部分请求弃用丢失。
可以看出漏斗算法能强行限制数据的传输速率。
令牌桶算法
从某种意义上来说,令牌算法是对漏斗算法的一种改进。对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发情况。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。
令牌桶算法是指一个固定大小的桶,可以存放的令牌的最大个数也是固定的。此算法以一种 固定速率 不断的往桶中存放令牌,而每次请求调用前必须先从桶中获取令牌才可以。否则进行拒绝或等待,直到获取到有效令牌为止。如果桶内的令牌数量已达到桶的最大允许上限的话,则丢弃令牌。
Golang标准库中的限制算法是基于令牌桶算法(Token Bucket) 实现的,库名为golangorg/x/time/rate
对于限流器的消费方式有三种,分别为 Allow()、 Wait()和 Reserve()。前两种内部调用的都是Reserve() ,每个都对应一个XXXN()的方法。如Allow()是AllowN(t, 1)的简写方式。
主要用来限速控制并发事件,采用令牌池算法实现。
使用 NewLimiter(r Limit, b int) 函数创建限速器,令牌桶容量为b。初始化状态下桶是满的,即桶里装有b 个令牌,以后再以每秒往里面填充 r 个令牌。
允许声明容量为0的限速器,此时将会拒绝所有 *** 作。
// As a special case, if r == Inf (the infinite rate), b is ignored
有一种特殊情况,就是 r == Inf 时,此时b参数将被忽略。
Limiter 提供了三个主要函数 Allow, Reserve, 和 Wait 大部分时候使用Wait。其中 AllowN, ReserveN 和 WaitN 允许消费n个令牌。
每个方法都可以消费一个令牌,当没有可用令牌时,三个方法的处理方式不一样
AllowN方法表示,截止在某一时刻,目前桶中数目是否至少为n个。如果条件满足,则从桶中消费n个token,同时返回true。反之不消费Token,返回false。
使用场景:一般用在如果请求速率过快,直接拒绝请求的情况
输出
当使用Wait方法消费Token时,如果此时桶内Token数量不足(小于N),那么Wait方法将会阻塞一段时间,直至Token满足条件。否则直接返回。
// 可以看到Wait方法有一个context参数。我们可以设置context的Deadline或者Timeout,来决定此次Wait的最长时间。
输出
// 此方法有一点复杂,它返回的是一个Reservation类型,后续 *** 作主要针对的全是这个类型
// 判断限制器是否能够在指定时间提供指定N个请求令牌。
// 如果ReservationOK()为true,则表示需要等待一段时间才可以提供,其中ReservationDelay()返回需要的延时时间。
// 如果ReservationOK()为false,则Delay返回InfDuration, 此时不想等待的话,可以调用 Cancel()取消此次 *** 作并归还使用的token
输出
>
在 ci 过程中,经常有一些可以通过静态分析或者白盒检测去避免一些问题以及规范代码格式!使用Go语言一般是使用 golangci-line 作为代码检测工具!
参考官网:>
golang net/>
先配置Header最长读取时间、req最长读取时间、req最大读取长度默认6M。
RFC7230禁止\r\n参数,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_~4个特殊字符以及所有保留字符。但go net/>
以上就是关于Golang中的限速器 time/rate全部的内容,包括:Golang中的限速器 time/rate、golang-redis系列——返回值助手函数(二)、golangci-line 工具介绍等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)