在 fiber 应用中接入 sentinel go 需手动封装中间件,资源名应为“http方法:静态路径模板”(如 get:/api/v1/users/{id}),须在 handler 执行时动态创建 entry 并 defer exit,规则热更新需在 initdefault 后调用 flow.updateflowrules。

如何在 Fiber 应用中接入 Sentinel Go 客户端
直接用 sentinel-go 官方 SDK 即可,但要注意 Fiber 是 HTTP 框架,而 Sentinel Go 默认不提供 Fiber 中间件封装,必须手动桥接请求生命周期。官方 sentinel-http 模块只支持 net/http,所以得自己 wrap fiber.Handler。
关键点是:Sentinel 的资源定义(Entry)必须包裹在每个路由处理逻辑最外层,且需把 HTTP 方法 + 路径作为唯一 resource name,否则限流策略无法按接口维度生效。
- 引入依赖:
github.com/alibaba/sentinel-golang和github.com/gofiber/fiber/v2 - 初始化 Sentinel 时必须调用
sentinel.InitDefault(),否则后续entry创建会 panic - 不要在
fiber.Router.Add()阶段就创建 Entry——那是注册路由,不是处理请求;Entry 必须在 handler 执行时动态创建 - 推荐把 Sentinel 逻辑抽成一个
fiber.Handler,例如sentinelMiddleware(),然后用app.Use(sentinelMiddleware)全局挂载,或按路由选择性挂载
定义资源名时为什么不能用 raw URL 或 query 参数
因为 Sentinel 的资源粒度控制依赖稳定、可枚举的 resource name。如果把 /api/v1/users/123?trace_id=abc 整体当 resource,会导致每条请求都生成新 resource,规则无法命中,限流彻底失效。
正确做法是提取静态路径模板,比如 GET:/api/v1/users/{id},和 Fiber 内部的 c.Route().Path 结合使用(注意:Fiber v2.49+ 才稳定支持 c.Route() 返回非 nil)。
- Fiber v2.48 及更早版本中,
c.Route()在某些嵌套路由下可能返回 nil,此时应 fallback 到预设的路由标识常量 - 避免用
c.Path(),它返回的是带实际参数的路径(如/api/v1/users/123),不适合做 resource name - HTTP 方法必须参与拼接,因为
POST /api/v1/orders和GET /api/v1/orders通常需要不同阈值
限流规则不生效的三个常见原因
现象通常是:压测时 QPS 明显超限,但没触发 block 或降级,日志里也看不到 Blocked by flow rule。
- 忘记调用
entry.Exit():Fiber 的 panic 恢复机制可能吞掉异常,导致entry未被释放,后续请求因 entry 处于 busy 状态而直接拒绝(表现为“误杀”);务必用defer entry.Exit()且确保它在 handler 最外层执行 - 规则加载时机错误:在
sentinel.InitDefault()之前就调用了flow.LoadRules(),规则不会注册;应确保规则加载在 Init 之后、服务启动之前 - 资源名大小写或空格不一致:比如代码里写
GET:/api/v1/users,但规则 JSON 里配的是get:/api/v1/users,Sentinel 默认区分大小写,匹配失败即忽略规则
如何让 Sentinel 规则热更新并适配 Fiber 的优雅重启
Sentinel Go 支持从文件、Nacos、Apollo 等数据源监听规则变更,但 Fiber 的 Shutdown() 过程中若还有活跃的 entry,可能导致新旧规则混用,甚至 panic。
核心约束是:规则变更回调函数内不能阻塞,也不能直接操作 Fiber 的 App 实例;所有状态变更必须通过线程安全的 registry 或 channel 中转。
- 推荐用
fileWatcher方式做本地开发验证,生产环境优先对接Nacos(Go 客户端已原生支持) - 每次规则更新后,调用
flow.UpdateFlowRules(newRules)即可,无需重启应用 - Fiber 启动前,先调用
sentinel.InitDefault(),再加载初始规则;否则热更新第一次会失败 - 别在
fiber.App.Shutdown()回调里调用sentinel.Close()——它会清空内存中的规则缓存,影响正在处理的请求
entry 不是 request-scoped,而是 goroutine-scoped,而 Fiber 的 handler 可能被复用或跨 goroutine 调度,必须确保每个 handler 执行流都有独立、成对的 entry.Enter() / entry.Exit()。











