golang,go,博客,开源,编程

golang每日一库之RussellLuo/slidingwindow

Updated on with 0 views and 0 comments

RussellLuo/slidingwindow 是一个用 Go 语言实现的滑动窗口速率限制器,灵感来源于 Kong API 网关的限流算法。该库支持本地和分布式限流,适用于需要精确控制请求速率的场景。


设计理念

该库通过维护两个窗口(当前窗口和前一个窗口)的请求计数,估算当前时间点的请求速率,从而实现滑动窗口限流。

例如,设定每分钟最多允许 100 次请求:

  • 当前时间为第 75 秒,即当前窗口开始于第 60 秒。
  • 当前窗口内记录了 12 次请求。
  • 前一个窗口(第 0 秒到第 60 秒)内记录了 86 次请求。

则当前估算的请求数为:

count = 86 * ((60 - 15) / 60) + 12 = 86 * 0.75 + 12 = 76.5

如果 count 超过设定的阈值(例如 100),则拒绝新的请求。


主要组件

1. Limiter

Limiter 是速率限制的核心结构,负责判断是否允许新的请求。它通过维护两个窗口的计数来估算当前的请求速率。

主要方法:

  • Allow():判断是否允许一个新的请求。
  • AllowN(now time.Time, n int64):判断是否允许 n 个新的请求。
  • SetLimit(newLimit int64):设置新的请求限制。

2. Window

Window 接口定义了窗口的基本操作,包括添加计数、获取计数、重置窗口等。该库提供了两种实现:

  • LocalWindow:本地窗口,适用于单机应用。
  • SyncWindow:同步窗口,适用于分布式环境。

3. 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

适用场景

  • API 速率限制:控制每个用户或 IP 的请求频率。
  • 防止滥用:防止恶意用户发送过多请求。
  • 分布式系统:在多个服务实例之间共享限流状态。

RussellLuo/slidingwindow 提供了一个灵活且高效的滑动窗口限流解决方案,适用于多种应用场景。

其支持本地和分布式部署,能够满足不同规模系统的需求。


标题:golang每日一库之RussellLuo/slidingwindow
作者:mooncakeee
地址:http://blog.dd95828.com/articles/2025/05/22/1747898154900.html
联系:scotttu@163.com