Go 每日一库之一个兼具单机和集群模式的轻量级限流器 throttled
2022-9-12 22:1:39 Author: Go语言中文网(查看原文) 阅读量:13 收藏

今天给大家推荐的工具是一个轻量级的限流器,star:1.2k。该工具实现了对资源的访问速率限制,资源可以是特定的 URL、用户或者任何自定义的形式。比如针对HTTP API接口。该包基于通用信源速率算法(generic cell rate algorithm)实现的。其底层存储是内置了内存存储(memstore)和redis两种存储方式。可以根据具体的使用场景实现单机限流集群限流

基本使用

下面代码是实现了一个按请求 path 进行限流的 http 服务,允许同一个 path 每分钟 20 次请求,并支持最多 5 个并发请求的 burst:

package main
import ( "fmt" "log" "net/http"
"github.com/throttled/throttled/v2" "github.com/throttled/throttled/v2/store/memstore")
func main() { // 在 store 中添加 key 的数量限制 store, err := memstore.New(65536) if err != nil { log.Fatal(err) }
// 配置限流规则 quota := throttled.RateQuota{ MaxRate: throttled.PerMin(20), MaxBurst: 5, } rateLimiter, err := throttled.NewGCRARateLimiter(store, quota) if err != nil { log.Fatal(err) }
httpRateLimiter := throttled.HTTPRateLimiter{ RateLimiter: rateLimiter, // 根据 path 进行限流 VaryBy: &throttled.VaryBy{Path: true}, }
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello, world\n") }) http.ListenAndServe(":8080", httpRateLimiter.RateLimit(handler))}

多种形式的资源定义

此外,我们也可以通过指定 VaryBy 的方式对资源进行更多的定义。在VaryBy中我们可以通过Cookie、IP、HTTP的请求方法、HEADER头、请求查询参数等来更细粒度的定义资源。例如,若想对请求的来源IP进行访问限制,则可以进行如下配置:

httpRateLimiter := throttled.HTTPRateLimiter{  RateLimiter: rateLimiter,   VaryBy: &throttled.VaryBy{Path:true, RemoteAddr:true}}

自定义超限处理

资源访问超过限额后,HTTPRateLimiter默认提供了一个处理器是DefaultDeniedHandler。同时我们也可以通过自定义HTTPRateLimiter中的DeniedHandler属性来自定义超限后的输出。如下:

httpRateLimiter := throttled.HTTPRateLimiter{  RateLimiter: rateLimiter,    VaryBy: &throttled.VaryBy{Path:true, RemoteAddr:true}}
httpRateLimiter.DeniedHandler = http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "超过限额了", 429)}))
集群模式限流

throttled包中内置了memstore和redis存储模式。通过memstore存储限流配额 就是单机版的限流模式。如果想对集群进行统一限流则需要使用redis的存储模式。

实现原理

该包是基于GCRA算法实现的。该算法本质上是根据设置的速率来计算每一个请求的理论达到时间,如果该理论达到时间在最大允许通过的时间窗口之内,则允许该请求通过,否则直接丢弃掉。该算法兼具令牌桶的最大容量特性来适应突增的流量,同时也具有漏桶的匀速消耗的特性。

更多项目详情请查看如下链接 :

开源项目地址:https://github.com/throttled/throttled

参考资料:https://baike.baidu.com/item/通用信元速率算法/2083527


推荐阅读

福利
我为大家整理了一份从入门到进阶的Go学习资料礼包,包含学习建议:入门看什么,进阶看什么。关注公众号 「polarisxu」,回复 ebook 获取;还可以回复「进群」,和数万 Gopher 交流学习。


文章来源: http://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651453417&idx=1&sn=f89f441c7f045177863daa40ea204134&chksm=80bb291bb7cca00d5f4c35e3be35f3f33f1e8a43b7463575731e07cc0d6af51ebc5333b58593#rd
如有侵权请联系:admin#unsafe.sh