StrictRouting 默认为 true,是契约而非 bug;/users 和 /users/ 视为两个独立路径,匹配仍为 O(k) 无锁,关闭反而增加归一化和 fallback 开销。

路由配置不优化,QPS 上 2000 就可能开始抖动——不是 Radix 树慢,是你在匹配前就卡住了。
StrictRouting 开关选哪个?
StrictRouting 默认为 true,这不是 bug,是契约。它让 /users 和 /users/ 视为两个独立路径,匹配过程仍是 O(k)、无锁、零额外开销。
- 别关它:
StrictRouting: false会触发尾部斜杠归一化 + fallback 匹配逻辑,反而多字符串操作和潜在歧义(比如/users/:id被/users拦截) - 显式注册更安全:同时写
app.Get("/users", handler)和app.Get("/users/", redirectHandler) - 统一重定向也行:中间件里用
strings.HasSuffix(c.Path(), "/") && c.Path() != "/"判断,c.Redirect(strings.TrimSuffix(c.Path(), "/"), 301) - 上线前同步检查前端 SDK、OpenAPI spec、Postman 集合是否全用无尾斜杠路径,避免漏改
正则路由 vs 参数路由,性能差 3–5 倍
写 app.Get("/user/*", handler) 看似灵活,实则绕过 Radix 树最优路径,退化成线性扫描匹配;而 app.Get("/user/:id", handler) 是标准前缀树节点跳转,全程无反射、无正则编译开销。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 通配符
*只能放在路径末尾,且无法提取参数,后续还得手动strings.TrimPrefix() - 需要校验 ID 格式?用 Fiber v3 的
RegisterCustomConstraint,别在 handler 里写if !isValidID(c.Params("id")) - 多个可选层级?拆成明确路径:
/user/:id/profile、/user/:id/settings,别堆/user/*
路由注册必须在 Listen 前完成
Fiber 的 Radix 树启动后冻结,运行时匹配完全无锁。但如果你在 handler 或中间件里调 app.Add() 或动态改 app.Router,就会触发 fatal error: concurrent map writes。
- 所有
app.Get()、app.Post()必须放在main()顶部或初始化函数中,app.Listen()之前 - API 网关类场景需“按租户加载路由”?不能运行时注册,得预加载全量路由 + handler 内部逻辑分发
- 闭包里捕获的
map或slice不是线程安全的,哪怕只读也要加sync.RWMutex,别依赖“树安全”就忽略数据竞争
参数解析别掉进反射和拷贝坑
路由快没用,handler 里一写错,整个请求延迟就上去了。Fiber 的性能优势全靠绕过标准库反射和内存分配。
- 取路径参数用
c.ParamsInt("id"),不是strconv.Atoi(c.Params("id")):前者内置缓存、不 panic、少一次类型转换 - 读请求体用
c.BodyBytes(),不是c.Body():后者返回新拷贝的[]byte,前者直接返回底层引用(前提是你不修改内容) - JSON 解析慎用
c.BodyParser(&v):它触发反射;结构固定就预编译jsoniter.ConfigCompatibleWithStandardLibrary,或直接json.Unmarshal(c.BodyBytes(), &v) -
c.Params("id")、c.QueryParam("q")、c.FormValue("name")来源完全隔离,混用必空值
最常被忽略的是:路由层再快,一个没设超时的 DB 查询或 HTTP 调用,就能让 P95 延迟从 5ms 拉到 300ms——优化路由只是第一步,外部依赖的 deadline 和连接池大小,才是压测时真正卡脖子的地方。


















