压测时cpu飙升但rps不涨,大概率是echo调试日志未关闭:debug模式下echo.logger同步写控制台、带颜色和调用栈,单核cpu占用可达95%以上;生产环境须设e.logger.setlevel(log.error)或置空e.logger,禁用后cpu可降40%+。

压测时CPU飙升但RPS不涨,大概率是没关Echo调试日志
默认开启的Echo.Logger在debug模式下会同步写控制台、带颜色、带调用栈,单核CPU占用能冲到95%以上,尤其在wrk -c100并发下。这不是框架本身的问题,而是日志配置错误。
实操建议:
- 生产启动前必须调用
e.Logger.SetLevel(log.ERROR)或直接e.Logger = nil - 别用
echo.New()后手动挂载Logger中间件——那只是复制了一份,原logger还在后台刷屏 - 若用Zap或Zerolog做结构化日志,禁用
Echo.Logger后,所有日志走自定义中间件,CPU可降40%+
Fiber内存低不等于GC压力小,关键看ctx复用是否被破坏
Fiber的fiber.Ctx对象复用机制只在请求生命周期内生效。一旦你把它传进goroutine、塞进map缓存、或用context.WithValue跨层传递,fasthttp底层的内存池就失效,反而触发高频GC。
常见错误现象:
- 在handler里起goroutine处理异步任务,却把
c作为参数传入 → panic:cannot set header after written或内存泄漏 - 用
c.UserContext()存大量数据(比如整个DB连接池)→ 复用ctx变成“伪复用”,内存占用反超Gin - 误以为
fiber.Config{DisableStartupMessage: true}能省内存 → 它只关banner,对运行时无影响
对比CPU和内存不能只看top,得看pprof火焰图里谁在占主干
真实压测中,三者CPU热点几乎都集中在json.Marshal、database/sql.(*Rows).Next、zlog.Sugar.Infof上,框架调度函数(如fiber.(*App).handler或echo.(*Echo).ServeHTTP)通常只占火焰图2%~3%。
所以横向测评要这样比:
- 先统一关闭所有日志、禁用debug模式、固定
GOMAXPROCS=4 - 用
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30抓30秒CPU profile - 重点看
runtime.mallocgc上游调用链:Fiber里若出现fasthttp.RequestCtx.SetBodyString频繁调用,说明你用了字符串拼接响应而非预分配bytes.Buffer - 内存堆分析看
go tool pprof http://localhost:6060/debug/pprof/heap,Fiber的fasthttp.byteSlicePool应占堆顶,否则说明复用链断了
Fiber的低内存是fasthttp的副作用,对接标准组件时反而更耗资源
当你需要接入prometheus.Handler()或otelhttp.NewHandler()时,Fiber必须调用app.Handler()包装成标准http.Handler。这个转换不是零成本:每次请求都会新建*http.Request和http.ResponseWriter,绕过了fasthttp的复用优势。
此时内存表现可能反转:
- 纯Fiber路由:内存45MB(基准)
- 加
app.Use(func(c *fiber.Ctx) error { return c.Next() }):内存不变 - 加
http.Handle("/metrics", promhttp.Handler())并用app.Handler()桥接:内存升至58MB,GC频率回到net/http水平
真正卡住吞吐的从来不是框架名字,而是你有没有在fiber.Ctx里偷偷调了http.Error(),或者忘了把echo.HTTPErrorHandler设为panic兜底——这种错误会让一次请求多分配3个stack trace对象,比选错框架更伤。











