必须正确配置Limiter的存储后端、速率规则和键生成逻辑;内存存储仅用于单机调试,生产环境须用Redis;rate格式严格为“数字-单位”(如“50-M”);KeyFunc不可返回空字符串;限流中间件需挂载在鉴权之后、业务逻辑之前。

要在Fiber应用中精确控制每秒/每分钟的请求上限,必须正确设置Limiter中间件的存储后端、速率规则和键生成逻辑,漏掉任一环节都会导致限流失效或所有请求被误拦。
初始化Limiter实例
先创建限流器核心对象,它不依赖Fiber,但后续中间件需引用它。内存存储仅适用于单机调试,生产环境必须用Redis:
store := memory.NewStore() // 单机测试用
rate, _ := limiter.NewRateFromFormatted("50-M") // 表示每分钟50次
limiterInst := limiter.New(store, rate)
【rate参数格式必须严格为数字+单位,如"100-S"、"30-M"、"5-H",字母大小写敏感,空格或拼写错误会导致NewRateFromFormatted返回nil】
配置Fiber中间件选项
使用fiber.AdvanceRateLimiter时,需传入完整配置结构体,不能只传limiter实例:
方法一:按IP限流(最常用)
middleware := fiber.AdvanceRateLimiter(fiber.RateLimiterConfig{
Store: limiterInst,
KeyFunc: func(c *fiber.Ctx) string { return c.IP() },
ErrorHandler: func(c *fiber.Ctx) error { return c.Status(429).SendString("Too many requests") }
})
方法二:按用户ID限流(需从Header或Token提取)
KeyFunc: func(c *fiber.Ctx) string {
auth := c.Get("Authorization")
if len(auth) > 7 && strings.HasPrefix(auth, "Bearer ") {
token := auth[7:]
return parseUserIDFromToken(token) // 你自己的解析函数
}
return c.IP()
}
注意:KeyFunc返回空字符串会导致所有请求共享同一个计数器,造成大面积误拦截。
挂载到Fiber路由链
第一步:选择挂载粒度
① 全局限流:app.Use(middleware) → 所有路由生效
② 分组限流:api := app.Group("/api"); api.Use(middleware) → 仅/api开头路径生效
③ 单路由限流:app.Get("/pay", middleware, handler) → 精确到某接口
第二步:确保顺序正确
限流中间件必须放在鉴权之后、业务逻辑之前。如果先校验JWT再限流,可避免无效Token反复刷爆计数器;反之,非法请求也会被计入配额。
第三步:验证是否生效
启动服务后,用curl -I http://localhost:3000/连续请求,观察响应头中X-RateLimit-Remaining是否递减。若始终为初始值,说明KeyFunc未正确返回非空字符串或Store未生效。


















