限流器(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,
}))