Iris 必须手动集成 mongo-go-driver,启动时用 context.WithTimeout 建立全局复用的 mongo.Client 并 Ping 验证,退出前 Disconnect;handler 中通过闭包或 DI 传入预建的 mongo.Collection,所有 DB 操作必须使用请求上下文。

必须手动集成 mongo-go-driver,Iris 本身不提供 MongoDB 封装或自动连接能力。 所有连接复用、超时控制、上下文传递、优雅关闭都得自己写,硬连是唯一路径。
启动时建立全局复用的 *mongo.Client
Go 的 mongo-go-driver 客户端是线程安全的,*mongo.Client 必须只创建一次,挂载到 app 或包级变量上,不能在 handler 里反复 mongo.Connect()。
- 在
main()启动阶段用context.WithTimeout(context.Background(), 10*time.Second)包裹连接上下文,避免卡死 - 连接后立即调用
client.Ping(ctx, readpref.Primary())验证可用性,否则错误会延迟到首次查询才暴露 - 别忘了监听
os.Interrupt,在程序退出前调用client.Disconnect(ctx)—— Iris 没内置关机钩子 - 推荐把
*mongo.Client注入app.ConfigureContainer()(v12.2.11+),后续可 DI 获取
handler 中怎么拿到 collection 实例
不要在每个路由函数里重复写 client.Database("db").Collection("coll"),这虽轻量但易错、难测、难替换。
- 初始化时就构造好
*mongo.Collection:比如usersColl := db.Collection("users") - 用闭包传入 handler:
app.Get("/users", userHandler(usersColl)),清晰且无副作用 - 若用 DI 风格,需启用
app.ConfigureContainer()并注册*mongo.Collection类型,再在 handler 签名中声明接收(如func(ctx iris.Context, coll *mongo.Collection)) - 避免用
ctx.Values().Set()存 collection —— 值类型不安全,中间件可能覆盖,且无法被 DI 容器管理
所有 DB 操作必须用请求上下文,不能用 context.Background()
Find、InsertOne、UpdateByID 等所有操作都要求传 context.Context。传 context.Background() 会让数据库操作脱离 HTTP 生命周期,拖垮连接池,也无法响应客户端取消。
- 正确做法:从
iris.Context提取:ctx := c.Request().Context(),再按需加超时,例如ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - 错误写法:
coll.Find(context.Background(), filter)—— 这会导致请求已断开,MongoDB 查询还在跑 - 注意:即使用了
context.WithTimeout,也必须在操作结束后调用cancel(),否则 goroutine 泄漏
最容易被忽略的是上下文传递链路:从 HTTP 请求进来,到 handler,再到 collection 方法,必须一穿到底;任何一处漏掉或误用 context.Background(),都会让超时、取消、追踪全部失效。这不是“能跑就行”的细节,而是生产环境稳定性的分水岭。


















