fiber 不参与 mongodb 连接逻辑,实际使用的是 fiber + mongo-go-driver;所有连接、查询、错误处理均由驱动决定,fiber 仅负责 http 请求转发;mongo.connect 必须使用 context.withtimeout 包裹,否则服务启动可能无限阻塞,且需紧跟 defer cancel() 防止 context 泄漏。

直接说结论:Fiber 本身不参与 MongoDB 连接逻辑,你用的不是 “Fiber + MongoDB”,而是 “Fiber + mongo-go-driver”——所有连接、查询、错误处理都由驱动决定,Fiber 只负责把 HTTP 请求转给你的 handler 函数。
mongo.Connect 必须带 context.WithTimeout,否则服务启动就卡住
很多新手在 main.go 里写 mongo.Connect(context.Background(), options.Client().ApplyURI(uri)),结果部署到 Docker 或 Kubernetes 后,服务永远起不来,日志停在“connecting...”。这不是 Fiber 的问题,是驱动没超时控制。
- 必须用
context.WithTimeout(context.Background(), 10*time.Second)包裹,超时后返回context.DeadlineExceeded错误,而不是无限等待 -
defer cancel()要紧跟着mongo.Connect调用,否则 context 泄漏会拖慢 GC - 别复用同一个
ctx多次调mongo.Connect,每次都要新构造带 deadline 的 context - 本地开发可用
mongodb://localhost:27017,但上生产必须补全?authSource=admin&tls=true&tlsCAFile=/path/to/ca.pem
结构体字段不加 bson tag,Decode 就全为零值且不报错
Fiber handler 里调 collection.FindOne(ctx, filter).Decode(&post),结果 post.Title 是空字符串、post.CreatedAt 是零时间——大概率是结构体字段没写 bson tag,或者拼错了。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
ID primitive.ObjectID `bson:"_id,omitempty"`:下划线不能少,_id是 MongoDB 固定字段名 -
Title string `bson:"title"`:不能只写`json:"title"`,驱动不看jsontag - 嵌套字段如
User struct{ Name string `bson:"name"` },内层也要单独加 tag,不会继承外层前缀 -
CreatedAt time.Time `bson:"created_at"`:时间字段必须是time.Time类型,tag 值要和数据库存的 key 完全一致(大小写敏感)
Find() 游标不 Close,goroutine 和内存就一直泄漏
用 collection.Find(ctx, bson.M{"status": "published"}) 拿到 *mongo.Cursor 后,如果只循环 Next() 却忘了 Close(),每次请求都会多占一个 goroutine 和缓冲区,压测几分钟就 OOM。
- 必须在 handler 开头就
defer cursor.Close(ctx),ctx应该是当前 HTTP 请求的生命周期 context - 别跳过
cursor.Next()直接cursor.Decode(),会 panic - 批量数据用
cursor.All(ctx, &results)简单,但高并发或大数据量时建议流式处理,避免内存暴涨 - 检查游标错误要用
cursor.Err(),不是只看Next()返回值;字段类型不匹配时,Decode()不报错,cursor.Err()才会非 nil
Fiber 中传参给 MongoDB 查询要注意 bson.M 和类型对齐
Fiber 的 c.Params("id") 返回的是字符串,但 MongoDB 的 _id 是 primitive.ObjectID,直接塞进 bson.M{"_id": c.Params("id")} 查不到任何东西,也不报错。
- 先用
primitive.ObjectIDFromHex(c.Params("id"))转换,再检查err != nil(非法 ID 字符串) - 时间查询必须用 UTC:
bson.M{"created_at": bson.M{"$gte": time.Now().UTC().AddDate(0, 0, -7)}},本地时区会导致查不到 - 别用原生
map[string]interface{}构造 filter,一律用primitive.M{"name": "alice", "age": 30},否则时间、二进制字段会丢 - 空 filter 写
bson.M{},不是nil;传nil会导致游标为空,Next()立即返回 false
最常被忽略的点是:Fiber 的 ctx.Context() 和 MongoDB 驱动的 context.Context 是两回事,不能混用。Fiber 的 context 是 HTTP 生命周期封装,MongoDB 操作必须用它派生出的新 context(比如加 timeout),且每个 DB 调用都要显式传入——漏传、错传、复用,都会导致超时失控或资源泄漏。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










