golang,go,博客,开源,编程
RussellLuo/slidingwindow
是一个用 Go 语言实现的滑动窗口速率限制器,灵感来源于 Kong API 网关的限流算法。该库支持本地和分布式限流,适用于需要精确控制请求速率的场景。
该库通过维护两个窗口(当前窗口和前一个窗口)的请求计数,估算当前时间点的请求速率,从而实现滑动窗口限流。
例如,设定每分钟最多允许 100 次请求:
则当前估算的请求数为:
count = 86 * ((60 - 15) / 60) + 12 = 86 * 0.75 + 12 = 76.5
如果 count
超过设定的阈值(例如 100),则拒绝新的请求。
Limiter
Limiter
是速率限制的核心结构,负责判断是否允许新的请求。它通过维护两个窗口的计数来估算当前的请求速率。
主要方法:
Allow()
:判断是否允许一个新的请求。AllowN(now time.Time, n int64)
:判断是否允许 n
个新的请求。SetLimit(newLimit int64)
:设置新的请求限制。Window
Window
接口定义了窗口的基本操作,包括添加计数、获取计数、重置窗口等。该库提供了两种实现:
LocalWindow
:本地窗口,适用于单机应用。SyncWindow
:同步窗口,适用于分布式环境。Synchronizer
在分布式环境中,Synchronizer
负责在多个实例之间同步窗口的状态。该库提供了两种同步器:
BlockingSynchronizer
:阻塞式同步器。NonblockingSynchronizer
:非阻塞式同步器。以下是一个使用 LocalWindow
的示例,限制每分钟最多 100 次请求:
package main
import (
"fmt"
"time"
"github.com/RussellLuo/slidingwindow"
)
func main() {
// 创建一个本地窗口
window, stop := slidingwindow.NewLocalWindow()
defer stop()
// 创建一个限制器,限制每分钟最多 100 次请求
limiter := slidingwindow.NewLimiter(time.Minute, 100, func() (slidingwindow.Window, slidingwindow.StopFunc) {
return window, stop
})
// 模拟请求
for i := 0; i < 105; i++ {
if limiter.Allow() {
fmt.Println("请求被允许")
} else {
fmt.Println("请求被拒绝")
}
}
}
在上述示例中,前 100 次请求将被允许,之后的请求将被拒绝。
可以使用以下命令安装该库:
go get -u github.com/RussellLuo/slidingwindow
RussellLuo/slidingwindow
提供了一个灵活且高效的滑动窗口限流解决方案,适用于多种应用场景。
其支持本地和分布式部署,能够满足不同规模系统的需求。