跳至主要内容
版本:v2.x

限流器

用于 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 应用程序后,可以使用以下可能性

// Initialize default config
app.Use(limiter.New())

// Or extend your config for customization
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.

配置

属性类型说明默认值
下一个func(*fiber.Ctx) bool当返回 true 时,Next 定义了一个函数来跳过此中间件。nil
Maxint在发送 429 响应之前,在 Expiration 秒期间最近连接的最大数量。5
KeyGeneratorfunc(*fiber.Ctx) stringKeyGenerator 允许您生成自定义键,默认情况下使用 c.IP()。使用 c.IP() 作为默认值的一个函数
Expirationtime.DurationExpiration 是在内存中保留请求记录的时间长度。1 * time.Minute
LimitReachedfiber.Handler当请求达到限制时,将调用 LimitReached。发送 429 响应的函数
SkipFailedRequestsbool当设置为 true 时,StatusCode >= 400 的请求将不会被计数。false
SkipSuccessfulRequestsbool当设置为 true 时,StatusCode < 400 的请求将不会被计数。false
Storagefiber.StorageStore 用于存储中间件的状态。仅针对此进程的内存存储
LimiterMiddlewareLimiterHandlerLimiterMiddleware 是实现限流中间件的结构。新的固定窗口速率限制器
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() // From github.com/gofiber/storage/sqlite3
app.Use(limiter.New(limiter.Config{
Storage: storage,
}))