StrictRouting开启更快,因纯字符串前缀匹配免归一化开销;关闭反而引发路由冲突且多一次O(k)操作。

StrictRouting 开启反而更慢?其实是你关错了
StrictRouting 默认开启不是为了“卡你”,而是避免隐式归一化带来的额外开销。关掉它不会提速,反而可能让 /users 和 /users/:id 匹配冲突——比如请求 /users/123 被前者捕获,ctx.Params("id") 拿不到值。
StrictRouting = true 时,匹配是纯字符串前缀比对,Radix 树直接跳转,无同步开销;设为 false 后,框架要先做尾部斜杠归一(如 /users/ → /users),再查一次路由,多一次 O(k) 操作。
- 显式注册两种路径:
app.Get("/users", ...)和app.Get("/users/", ...) - 或用中间件统一 301 重定向,而不是全局关 StrictRouting
- 检查启动日志是否出现
WARNING: StrictRouting is disabled—— 出现即说明已误关
Prefork 开了 QPS 却没涨?先看 ulimit 和共享状态
Prefork 在 8 核机器上能将 QPS 推高 3 倍,但前提是系统资源跟得上。典型问题:启用 Prefork 后压测结果远低于预期,其实只是被 ulimit -n 卡死了。
每个子进程都需要独立的文件描述符,若系统仍为默认 1024,大量连接会被拒绝,且错误日志里往往只显示 “accept: too many open files”,容易误判为代码问题。
- 启动前必须执行:
ulimit -n 65536,或写入/etc/security/limits.conf - 各子进程内存完全隔离:
sync.Map、全局变量无法跨 worker 共享 - 缓存类逻辑需改用 Redis 或共享内存,不能依赖进程内 map
- 验证是否生效:启动日志中应出现多个
Worker PID: xxx,只有一条说明未生效
ctx.Body() 和 strconv.Atoi 是吞吐隐形杀手
ctx.Body() 会触发完整字节拷贝,实测在 4 核 8G 环境下,10K 并发时 GC 频次上升 3.2 倍,P99 延迟从 8ms 涨到 47ms。同理,反复调 strconv.Atoi(ctx.Params("id")) 既无缓存又易 panic。
Fiber 底层复用 fasthttp 内存池,但标准库惯用写法会绕过所有优化,让高并发迅速退化成 net/http 水平。
- 改用
ctx.BodyBytes()直接取[]byte引用(注意:修改前需copy()) - ID 类参数解析放到中间件里一次性完成:
id, err := c.ParamsInt("id"),它内建缓存且不 panic - JSON 返回优先用
c.JSON(200, data),而非json.Marshal+c.Send() - 避免在 handler 中拼接字符串,改用
bytes.Buffer或预分配[]byte
fiber.Default() 上线即崩?New() + 显式配置才是生产姿势
fiber.Default() 是开发快捷键,自带 Logger、Recover、RequestID,但上线后每秒数百条日志会拖垮磁盘 I/O,Recover 中未限流的 panic 日志还会引发刷屏雪崩。
它默认打印完整请求头(含 Authorization),不仅性能差,还违反安全规范。
- 上线必须用
fiber.New(&fiber.Config{...}),禁用所有默认中间件 - 必加配置:
DisableStartupMessage: true、EnablePrintRoutes: false - ReadBufferSize / WriteBufferSize 建议设为
4096或8192,太小频繁 syscall,太大浪费内存 - 超时控制别用
context.Context().Done()(fasthttp 不兼容),改用c.Context().SetDeadline()
真正卡住性能的往往不是框架选型,而是那些看似无害的“顺手写法”——比如在中间件里塞了个 log.Println,或者把数据库连接挂进 ctx.Locals 却忘了它只是引用。这些点不显眼,但并发一上来就立刻暴露。



















