上线必须用fiber.New()而非fiber.Default(),因后者自带中间件导致Authorization头泄露、TTFB增加0.3–0.8ms、高并发压垮QPS;StrictRouting使/users与/users/视为不同路径而404,应显式注册或重定向。

上线项目必须用 fiber.New() 初始化,别碰 fiber.Default()——后者自带日志、恢复、请求 ID 中间件,会泄露 Authorization 头、拖慢 TTFB 0.3–0.8ms,高并发下直接压垮 QPS。
fiber.New() vs fiber.Default() 怎么选
开发阶段用 fiber.Default() 没问题,它自动挂上 Logger、Recover、RequestID,省得手动写中间件;但上线前必须切到 fiber.New(),否则每秒几百条含敏感头的完整请求日志会吃光 I/O。
-
fiber.Default()是快捷入口,适合本地验证逻辑,不是生产配置 -
fiber.New()是空应用,什么中间件都没有,性能起点干净 - 真要日志,用采样策略(比如只记 error)或对接结构化日志系统,别用
fiber.Logger() - 如果硬要用
fiber.Default()上线,等于主动放弃对响应头、TTFB、错误传播链的控制
StrictRouting 导致 /users 和 /users/ 都 404 怎么办
Fiber 默认开启 StrictRouting: true,把 /users 和 /users/ 当作两个路由。你只注册了 app.Get("/users", handler),那访问 /users/ 就必然 404——这不是 bug,是路径匹配规则生效了。
- 别全局关掉:
fiber.New(&fiber.Config{StrictRouting: false}),否则/users/123可能被/users错误匹配,c.Params("id")拿不到值 - 推荐显式注册两条:
app.Get("/users", handler)和app.Get("/users/", redirectHandler) - 或加统一重定向中间件:
if strings.HasSuffix(c.Path(), "/") && c.Path() != "/" { c.Redirect(strings.TrimSuffix(c.Path(), "/"), 301) } - 上线前同步检查前端路由、SDK 调用、OpenAPI 文档,确保全用无尾斜杠路径
ctx.QueryParam、ctx.Params、ctx.FormValue 到底该用哪个
三者来源完全不同,混用必空,且无法 fallback:
-
c.QueryParam("q")只读 URL query string,比如/search?q=go中的q -
c.Params("id")只读路由占位符,比如app.Get("/user/:id", )匹配/user/123后的123 -
c.FormValue("name")是给application/x-www-form-urlencoded准备的;JSON body 必须用c.Body()+json.Unmarshal或c.Struct(&v) - 用错会导致参数始终为空,调试时先打
c.Path()和c.Request().URI().QueryString()看原始输入
ctx.Next() 为什么没执行后续 handler
ctx.Next() 不是“继续跑下一个中间件”,而是把控制权交还给 Fiber 调度器——它是否继续往后走,取决于当前 handler 是否已写入响应(如调了 c.Send()、c.JSON()、c.Status(401).Send())。
- 权限中间件里判断失败后写了
c.Status(401).Send("unauthorized"),再调c.Next(),响应已发出,Fiber 直接终止链路 - 拒绝请求就直接
return,别碰c.Next();放行才调 - 调试时在每个中间件开头加
log.Println("in auth middleware"),看执行流卡在哪一环 - 注意:Fiber 的
ctx是复用对象,返回值不能跨 handler 保存引用
最易被忽略的是 ctx.Body() 和 strconv.Atoi(ctx.Params("id")) 这类操作——它们触发内存分配,让底层 fasthttp 的零拷贝优势失效,性能退化回 net/http 水平。











