fiber 默认配置不适用于高并发,需关闭调试日志、禁用启动提示和路由打印;避免反射与内存拷贝,优先使用零拷贝api和预编译json;超时必须用setdeadline,db连接池需匹配核数;禁用prefork和静态中间件滥用。

Fiber 默认配置根本扛不住高并发,不是框架不行,是默认开了一堆调试和日志开关,还混着低效写法——上线前不调优,QPS 上 2 万就可能开始抖动丢包。
fiber.New() 初始化必须关掉调试和启动日志
默认 fiber.New() 会打印路由树、启动提示、彩色日志,这些在压测时全是 CPU 和 I/O 开销。关键配置只有两个:禁用启动消息 + 关闭路由打印。
-
DisableStartupMessage: true—— 干掉那一行⇨ http server started on http://localhost:3000 -
EnablePrintRoutes: false—— 路由树不打印,否则上几百个路由时初始化慢 100ms+ - 别信
fiber.Default(),它自带Logger和Recover,上线即拖垮 QPS - 如果用了
app.Use(logger),压测前必须删掉;真要日志,换异步采样版(比如只记 error)
路由和参数解析别踩反射和拷贝坑
Fiber 的性能优势全靠绕过标准库的反射和内存分配,一旦用错 API,QPS 直接打七折。
- 路径参数优先用
c.ParamsInt("id"),不是strconv.Atoi(c.Params("id"))—— 前者内置缓存且不 panic - 请求体别用
c.Body(),改用c.BodyBytes()—— 后者返回底层[]byteslice,零拷贝 - JSON 解析能不用
c.BodyParser(&v)就不用,它触发反射;如果结构固定,提前用jsoniter.ConfigCompatibleWithStandardLibrary.Marshal()预编译 - 别写正则路由
app.Get("/user/*", handler),匹配比app.Get("/user/:id", handler)慢 3–5 倍
超时控制必须用 SetDeadline,别碰 context.WithTimeout
fasthttp 不兼容标准 context.Context 的超时机制,c.Context().Done() 在 Fiber 里根本不会触发 cancel。
- 所有外部调用(HTTP client、DB 查询、Redis)前必须设 deadline:
c.Context().SetDeadline(time.Now().Add(3 * time.Second)) - 别依赖中间件统一加超时——每个 handler 自己控,因为
ctx.Context()是 per-request 的原生 context,生命周期一致 - 数据库连接池大小要匹配并发数,比如 16 核机器,pgx 连接池设 32–64,否则大量 goroutine 卡在 acquire 上
- 时间类阻塞操作(如
time.Sleep)绝对禁止出现在 handler 中,它会让整个 goroutine 挂起,P99 延迟直接起飞
Prefork 和静态文件服务要按场景开关
Prefork 不是银弹,开错反而更慢;静态文件走 Fiber 中间件也是常见性能黑洞。
-
Prefork: true只在 ≥8 核、SSD、连接数持续 >5 万时才考虑;小规模部署开了会增加进程调度开销 - 开 Prefork 后,
app.Shutdown()必须监听os.Interrupt,否则子进程残留 - 静态资源别用
app.Use(func(c *fiber.Ctx) error { ... })处理,直接上app.Static("/", "./public", fiber.Static{Next: func(c *fiber.Ctx) bool { return false }}) - 确保
Next返回false,避免请求穿透到后续路由,否则每个静态请求都多走一遍 Radix 树
真正卡住高并发的往往不是路由匹配,而是你在 handler 里同步调了个没设 timeout 的 HTTP 请求,或者把大结构体塞进 c.Locals 导致 GC 尖刺——这些细节不盯住,调再多参数也没用。











