Fiber默认配置无法支撑百万并发,因其性能受限于未调优的OS参数、冗余日志、低效路由、同步I/O及业务阻塞;需关闭调试、禁用日志、设合理缓冲区、用SetDeadline、避免反射解析等。

为什么 Fiber 默认配置扛不住百万并发
Fiber 的底层是 fasthttp,它本身不依赖 net/http 的 goroutine-per-connection 模型,理论上单机几万并发很轻松。但“百万级”不是靠框架选型决定的,而是由操作系统限制、连接复用策略、中间件开销和业务逻辑阻塞共同决定的。默认启动一个 fiber.New() 实例,没调优就压测,大概率在 2–5 万 QPS 就开始丢包或延迟飙升——这不是 Fiber 不行,是没关掉调试开关、没禁用日志、没设对 ReadTimeout/WriteTimeout。
-
fiber.Config{DisableStartupMessage: true, EnablePrintRoutes: false}必加,避免启动时打印路由树消耗 CPU - 所有中间件(尤其是
logger)在压测前必须移除或替换为异步写入版本 -
ReadBufferSize和WriteBufferSize建议设为4096或8192,太小会频繁 syscall,太大浪费内存 - 别用
context.Context().Done()做超时控制——fasthttp不兼容标准 context 超时,要用c.Context().SetDeadline()
如何让 Fiber 真正跑满网卡和 CPU
单进程 Fiber 要打满千兆网卡(约 125 MB/s),需要至少 3–5 万长连接或 8–10 万短连接/秒;要吃满 16 核 CPU,得确保没有全局锁、无阻塞系统调用、无 GC 尖刺。关键不是加 goroutine,而是减少每个请求的路径长度。
- 路由匹配用
app.Get("/user/:id", handler),别写正则路由app.Get("/user/*", ...),后者性能差 3–5 倍 - 参数解析优先用
c.Params("id"),不用c.Query("id")或c.Body()解析 JSON——除非真需要。JSON 解析(c.BodyParser(&v))会触发反射和内存分配,QPS 直接掉 30%+ - 静态文件服务别走 Fiber 中间件,用
app.Static("/", "./public")并设置Next: func(c *fiber.Ctx) bool { return false }避免穿透 - 如果返回固定结构体,提前编译 JSON:用
jsoniter.ConfigCompatibleWithStandardLibrary.Marshal()替代json.Marshal(),快 20% 左右
连接层瓶颈在哪?怎么查
压测时 ab 或 hey 报 connect: cannot assign requested address 或大量 TIME_WAIT,说明客户端或服务端的 socket 资源耗尽,和 Fiber 无关,是 Linux 网络栈配置问题。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 服务端:检查
/proc/sys/net/core/somaxconn(建议 ≥ 65535)、/proc/sys/net/core/netdev_max_backlog(≥ 5000) - 客户端(压测机):改
/proc/sys/net/ipv4/ip_local_port_range为1024 65535,加/proc/sys/net/ipv4/tcp_tw_reuse = 1 - 用
ss -s看当前 socket 状态,重点关注tw(TIME_WAIT)和orphan数量;用go tool trace看 Goroutine block 在哪(常见于 DNS 解析、数据库 dial、日志 flush) - Fiber 自身不管理连接池,DB 或 Redis 连接必须用带连接池的驱动(如
pgxpool、redis-go/radix/v4),且池大小 ≠ CPU 核数,通常设为min(32, CPU*4)
真正卡百万并发的,从来不是框架本身
你写一个空 app.Get("/", func(c *fiber.Ctx) error { return c.SendStatus(200) }),本地压测能到 15 万+ QPS;但只要加一行 log.Printf("req") 或 time.Sleep(1 * time.Millisecond),立刻掉到 3 千以下。真实业务里,慢查询、串行 HTTP 调用、未关闭的 io.Copy、未复用的 bytes.Buffer,才是吞掉并发能力的黑洞。
立即学习“go语言免费学习笔记(深入)”;
别迷信“Fiber 百万并发”的 benchmark 截图。那个数字只在 echo、no-op、零分配、全内存计算时成立。上线前务必用 pprof 抓 30 秒生产流量 profile,重点看 runtime.mallocgc 和 net.(*pollDesc).wait 占比——超过 15%,就得砍分配或换异步 I/O。


















