一架梯子,一头程序猿,仰望星空!
Go Fiber教程 > 内容正文

Go Fiber Limiter限流


限流器(limiter)

这是一个用于 Fiber的中间件,用于限制对公共API和/或端点(例如密码重置)的重复请求。它还对于API客户端、网络爬虫或其他需要限制速率的任务非常有用。

注意: 此中间件使用我们的 Storage 包来支持各种数据库,通过一个统一的接口。默认配置将数据保存在内存中,可以查看下面的示例了解其他数据库。

注意: 默认情况下,此模块不与其他进程/服务器共享状态。

签名

func New(config ...Config) fiber.Handler

示例

导入作为 Fiber web框架一部分的中间件包:

import (
  "github.com/gofiber/fiber/v2"
  "github.com/gofiber/fiber/v2/middleware/limiter"
)

在创建 Fiber app 后,您可以使用以下可能性:

// 初始化默认配置
app.Use(limiter.New())

// 或者扩展自定义配置
app.Use(limiter.New(limiter.Config{
    Next: func(c *fiber.Ctx) bool {
        return c.IP() == "127.0.0.1"
    },
    Max:          20,
    Expiration:     30 * time.Second,
    KeyGenerator:          func(c *fiber.Ctx) string {
        return c.Get("x-forwarded-for")
    },
    LimitReached: func(c *fiber.Ctx) error {
        return c.SendFile("./toofast.html")
    },
    Storage: myCustomStorage{},
}))

滑动窗口

您可以启用滑动窗口算法,而不是使用标准的固定窗口算法。

示例配置如下:

app.Use(limiter.New(limiter.Config{
    Max:            20,
    Expiration:     30 * time.Second,
    LimiterMiddleware: limiter.SlidingWindow{},
}))

这意味着每个窗口将考虑到前一个窗口(如果有的话)。给定速率的公式为:

weightOfPreviousWindpw = previous window's amount request * (whenNewWindow / Expiration)
rate = weightOfPreviousWindpw + current window's amount request.

配置

属性 类型 描述 默认值
Next func(*fiber.Ctx) bool Next 定义一个函数,在返回 true 时跳过此中间件。 nil
Max int Expiration 秒内的最大连接数,超过则返回 429 响应。 5
KeyGenerator func(*fiber.Ctx) string KeyGenerator 允许您生成自定义键,默认使用 c.IP()。 使用 c.IP() 的函数作为默认值
Expiration time.Duration Expiration 是在内存中保持请求记录的时间。 1 * time.Minute
LimitReached fiber.Handler 当请求达到限制时调用 LimitReached。 发送 429 响应的函数
SkipFailedRequests bool 如果为 true,则不计算 StatusCode >= 400 的请求。 false
SkipSuccessfulRequests bool 如果为 true,则不计算 StatusCode < 400 的请求。 false
Storage fiber.Storage Store 用于存储中间件的状态。 仅当前进程的内存存储
LimiterMiddleware LimiterHandler LimiterMiddleware 是实现限流器中间件的结构体。 一个新的固定窗口速率限制器
Duration (过时) time.Duration 已弃用:使用 Expiration 替代 -
Store (过时) fiber.Storage 已弃用:使用 Storage 替代 -
Key (过时) func(*fiber.Ctx) string 已弃用:使用 KeyGenerator 替代 -

注意: 如果自定义存储实现了Storage接口,则可以使用自定义存储 - 有关详细信息和示例,请参阅store.go

默认配置

var ConfigDefault = Config{
    Max:        5,
    Expiration: 1 * time.Minute,
    KeyGenerator: func(c *fiber.Ctx) string {
        return c.IP()
    },
    LimitReached: func(c *fiber.Ctx) error {
        return c.SendStatus(fiber.StatusTooManyRequests)
    },
    SkipFailedRequests: false,
    SkipSuccessfulRequests: false,
    LimiterMiddleware: FixedWindow{},
}

自定义存储/数据库

您可以使用我们 storage 包中的任何存储方式。

storage := sqlite3.New() // 来自 github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
    Storage: storage,
}))