必须使用官方驱动 go.mongodb.org/mongo-driver/mongo,旧版 mgo 不兼容 MongoDB 4.4+ 认证;需正确配置 URI、TLS、超时 context,并显式 Ping 验证连接,合理管理 client 生命周期与 cursor 关闭。

MongoDB 驱动已不支持 gopkg.in/mgo.v2,必须用官方 go.mongodb.org/mongo-driver/mongo —— 否则连接会静默失败或 panic。
安装正确驱动并初始化 client
旧版 mgo 已归档且不兼容 MongoDB 4.4+ 的认证机制(如 SCRAM-SHA-256),新项目只能用官方驱动。安装命令:
go get go.mongodb.org/mongo-driver/mongo go get go.mongodb.org/mongo-driver/mongo/options go get go.mongodb.org/mongo-driver/mongo/readpref
初始化时需显式设置超时、上下文和连接选项:
-
options.Client().ApplyURI("mongodb://localhost:27017")是最简写法,但生产环境必须加options.Client().SetConnectTimeout(10 * time.Second) - 不要直接用
context.Background()调用mongo.Connect(),应传入带超时的 context,例如ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - 连接后务必调用
client.Ping(ctx, readpref.Primary())验证连通性,否则错误可能延迟到第一次查询才暴露
处理连接字符串中的认证与 TLS
本地开发常用 mongodb://localhost:27017,但上生产必须含用户名、密码和数据库名,格式为:mongodb://user:pass@host:port/dbname?authSource=admin。
立即学习“go语言免费学习笔记(深入)”;
-
authSource参数不能省:若用户在admin库创建,但想操作myapp库,就必须指定authSource=admin,否则报not authorized on myapp to execute command - 启用 TLS 时,必须加
?tls=true&tlsInsecure=true(测试)或?tls=true&tlsCAFile=/path/to/ca.pem(生产),否则连接会卡住或返回connection refused - URI 中的特殊字符(如密码含
/或@)必须 URL 编码,可用url.PathEscape()处理,否则解析失败且错误信息极不明确
避免常见 context 取消和资源泄漏
mongo.Client 是长生命周期对象,不应每次请求都新建;但它的 Disconnect() 必须被显式调用,否则进程退出时连接不释放。
- 全局声明
var client *mongo.Client,在init()或main()开头完成 Connect 和 Ping,程序退出前用defer client.Disconnect(context.TODO()) - 不要在 HTTP handler 内直接用
client.Database(...).Collection(...).Find(),Find 返回的*mongo.Cursor必须调用Close(),否则内存泄漏;推荐用for cursor.Next(ctx) { ... }+defer cursor.Close(ctx) - 如果 handler 中需要独立超时控制(比如查库不能超过 3 秒),应新建子 context:
ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second); defer cancel(),而不是复用 request context
真正麻烦的不是连上数据库,而是连接池参数调优、WriteConcern 设置、以及游标没 Close 导致的 goroutine 泄漏——这些不会立刻报错,但压测时会突然崩掉。










