生产环境必须用fiber.new()而非fiber.default(),因后者默认启用logger等中间件导致日志泄露、ttfb增加0.3–0.8ms;strictrouting开启时需显式注册或重定向尾斜杠路径,避免404或路由错配。

用 fiber.New() 初始化,别碰 fiber.Default()
上线服务必须用 fiber.New(),fiber.Default() 是开发玩具用的——它默认挂了 Logger、Recover、RequestID 中间件。生产环境开着它,每秒几百条含 Authorization 头的完整请求日志会压垮 I/O,实测 TTFB 增加 0.3–0.8ms。
正确做法是:
- 开发阶段用
fiber.Default()快速验证逻辑 - 上线前切到
fiber.New(&fiber.Config{...}),再按需手动加中间件(比如只记录 error 的采样日志) - 真要结构化日志,对接
zerolog或zap,别依赖fiber.Logger()
路由注册要显式处理结尾斜杠,别关 StrictRouting
StrictRouting 默认为 true,意味着 /users 和 /users/ 是两个不同路由。只注册了前者,访问后者就 404;若强行设为 false,又可能让 /users/123 被 /users 错误匹配,c.Params("id") 拿不到值。
稳妥方案是:
- 显式注册两种路径:
app.Get("/users", handler)和app.Get("/users/", handler) - 或加一层重定向中间件,把带尾部斜杠的请求 301 跳转到无斜杠版本
- 避免在路由设计阶段埋下歧义,而不是靠开关“修”
权限中间件里拒绝请求就 return,别调 ctx.Next()
常见翻车:鉴权失败后写了 c.Status(401).Send("unauthorized"),紧接着又写 c.Next()。此时响应头和体已发出,Fiber 直接终止链路,后续所有 handler 全被跳过,但开发者还以为“流程继续走了”。
关键原则:
- 拒绝请求 → 写完响应后直接
return,绝不碰ctx.Next() - 放行请求 → 才调
ctx.Next()让控制权交还调度器 - 调试时可在每个中间件开头加
log.Println("in auth middleware"),看执行流卡在哪一环
MongoDB 连接必须带 context.WithTimeout,且结构体字段要写 bson tag
Fiber 不参与 MongoDB 连接逻辑,你实际用的是 mongo-go-driver。不加超时控制,mongo.Connect() 在网络异常或 DNS 解析失败时会无限阻塞,Docker/K8s 环境下服务永远起不来。
必须这样写:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
另外,Decode() 失败但不报错,大概率是结构体字段缺 bson tag:
-
ID primitive.ObjectID `bson:"_id,omitempty"`—— 下划线不能少,_id是 MongoDB 固定字段名 -
Title string `bson:"title"`—— 不能只写json:"title",驱动不读jsontag -
CreatedAt time.Time `bson:"created_at"`—— tag 值必须和数据库存的 key 完全一致(大小写敏感)
还有个隐形坑:Find() 返回的 *mongo.Cursor 必须手动 Close(),否则 goroutine 和内存持续泄漏,压测几分钟就能明显感知。











