连接失败应先检查 MongoClient.connect() 的 Promise 状态;需显式 await、配置 retryWrites 和 w=majority;确认 mongod 运行;合理设置 maxPoolSize(建议 20 起)、minPoolSize 和 maxIdleTimeMS;useUnifiedTopology: true 必须开启;生产禁用 autoIndex,索引应显式创建并验证。

连接失败时先检查 MongoClient.connect() 的 Promise 状态
很多报错如 ServerSelectionError 或 TimeoutError 并非网络不通,而是连接逻辑没等 Promise settle 就执行了后续操作。Mongoose 内部也基于原生 Driver,但默认封装了连接重试和延迟初始化,容易掩盖底层问题。
- 用原生 Driver 时,
await MongoClient.connect(uri)必须显式await,不能只调用不等待 - 连接字符串里别漏掉
?retryWrites=true&w=majority,否则在 4.0+ 集群上可能因写关注策略触发静默失败 - 本地测试用
mongodb://localhost:27017时,确认 mongod 进程真在运行——ps aux | grep mongod比“应该开着”更可靠
连接池配置:不是越大越好,maxPoolSize 要匹配实际并发量
默认 maxPoolSize=100 看似保险,但在低配服务器或高频短连接场景下,反而导致 socket 耗尽、TIME_WAIT 堆积,甚至触发 Linux 的 net.ipv4.ip_local_port_range 限制。
- Web 应用常见并发请求在 50–200 之间,建议从
maxPoolSize=20起步,配合压测调整 - Node.js 单线程 + 异步 I/O,通常不需要每个请求独占一个连接;连接复用率高时,
minPoolSize=5能减少冷启动延迟 - 设置
maxIdleTimeMS=60000(1 分钟),避免空闲连接长期占用端口,尤其在容器环境重启频繁时
Mongoose 的 useUnifiedTopology: true 不是可选项,是必须项
这个选项关闭后,Driver 会降级使用旧的服务器发现机制,在 MongoDB 4.4+ 上大概率触发 TopologyDescriptionChangedEvent 频繁日志,且无法正确处理分片集群的路由变更。
- 所有 Mongoose 版本 ≥ 6.0 默认开启,但如果你还在用 5.x,请手动设为
true - 它和
useNewUrlParser: true是绑定关系:后者解析连接字符串格式,前者管理拓扑状态;两个都关等于裸连老协议 - 开启后,
mongoose.connection.readyState才能准确反映连接状态(0=disconnected, 1=connected, 2=connecting, 3=disconnecting)
生产环境必须禁用 autoIndex: true,索引要显式建
开发时开它很省事,但上线后每次启动都扫描 Model 定义、比对字段、自动创建索引——不仅拖慢启动速度,还会在副本集主节点上触发写操作,干扰正常业务流量。
- Mongoose 6+ 默认
autoIndex=false,但老项目迁移时容易忽略这个 breaking change - 索引应通过
db.collection.createIndex()或 migration 脚本统一管理,而不是靠应用启动时“顺便建” - 如果依赖 Mongoose 的
index: true字段定义,务必在部署后手动运行Model.init()一次,否则定义不会生效
mongostat 或 Atlas 的 Metrics 页面盯 5 分钟连接数曲线,比读十遍文档管用。










