定位
Fiber 是基于 fasthttp 的 Go Web 框架,API 风格照搬 Express。它的卖点只有一个:快。
代价也明确:不兼容 net/http,所以整个 Go 标准库生态的中间件、监控、pprof 都用不了。
安装
go mod init example.com/fiber-demo
go get github.com/gofiber/fiber/v3
Fiber 已经到 v3,要求 Go 1.25+,和 v2 的 API 有差异(主要是 Ctx 的方法签名和配置项)。网上大量教程还是 v2,抄代码时注意版本。
最小可运行示例
package main
import "github.com/gofiber/fiber/v3"
func main() {
app := fiber.New()
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("Hello")
})
app.Get("/users/:id", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"id": c.Params("id")})
})
app.Listen(":8080")
}
核心概念
1. 一切围绕 fasthttp
fasthttp 为了性能做了激进优化:复用请求和响应对象,不遵循 net/http 的 Request / ResponseWriter 接口。
好处是快(内存分配少)。坏处是下面这条铁律。
2. 绝对不要持有 Ctx
// 错误:c 在 handler 返回后会被复用到下一个请求
app.Get("/bad", func(c fiber.Ctx) error {
go func() {
time.Sleep(time.Second)
log.Println(c.Params("id")) // 可能读到别人的请求数据
}()
return nil
})
// 正确:显式拷贝一份——fasthttp 复用底层缓冲区,Params 返回的 string 仍指向它
app.Get("/ok", func(c fiber.Ctx) error {
raw := c.Params("id")
id := string(append([]byte(nil), raw...)) // 或 utils.CopyString(raw)
go func() {
time.Sleep(time.Second)
log.Println(id)
}()
return nil
})
这是 Fiber 最容易出的事故:数据错乱、串号,而且难复现。凡是异步、goroutine、队列里用到请求数据的地方,都要先拷贝。嫌手动拷贝麻烦,可以 fiber.New(fiber.Config{Immutable: true})——框架把所有从 Ctx 取出的字符串都换成安全副本,代价是分配与 GC 压力上升,所以默认关闭;示例里的 utils.CopyString(raw) 是同一件事的单点版本。
3. Express 式中间件链
app.Use(func(c fiber.Ctx) error {
start := time.Now()
err := c.Next() // 执行后续 handler
log.Printf("%s %s %v", c.Method(), c.Path(), time.Since(start))
return err
})
c.Next() 之前的代码在请求前执行,之后的在响应后执行——和 Express 完全一致。
4. 内置能力比 Gin 多
Fiber 自带静态文件、模板渲染、WebSocket、限流、压缩、CORS,不需要额外找中间件。这是对「生态不兼容」的补偿。
常见坑
① 用不了 net/http 中间件
Prometheus 的 promhttp、pprof、go-chi 的中间件、各种 APM 的 SDK——全部要自己写适配层。选 Fiber 前先列一遍你要用的第三方库。
② 参数绑定不区分类型
v2 的 c.ParamsInt("id") 在 v3 已移除:取整型参数改用泛型 c.Params[int]("id")(解析失败返回 error);请求到结构体的绑定统一走 c.Bind(),比如 err := c.Bind().All(&in) 会把 query、params、body 一次绑进结构体。默认值仍要自己处理,不如 Gin/Echo 的 struct 绑定省心。
③ HTTP/2 支持不完整
fasthttp 对 HTTP/2 的支持有限。如果前面挂了 nginx 做 TLS 终结,通常没问题;直接对外提供 HTTP/2 要注意。
什么时候选它
- 追求吞吐量,压测数据是硬指标
- 团队从 Node.js/Express 过来,想零学习成本
- 内部服务,不需要大量第三方中间件
不选它的场景:需要标准库生态(监控、链路追踪、pprof)、团队里有人会踩「持有 Ctx」的坑而无法自查。
性能的现实
Fiber 的 benchmark 数据确实比 Gin 好看,但是同一量级内的领先,不是数量级的差距。而且这个差距在真实业务里几乎无感——接口耗时的大头在 SQL 和下游调用,框架自身那一小截开销用户看不出区别。
如果性能是你的核心诉求,先优化 SQL 和缓存,那才是 10 倍级的差距。
延伸阅读
- Echo 框架入门——标准库生态路线的对照选择