MongoDB Node.js驱动v4+默认内置自动重连,但需全局单例 MongoClient、合理配置 serverSelectionTimeoutMS 等参数,避免新建实例或主动 close;否则看似“未重连”实为误用。

默认情况下,MongoDB Node.js 驱动(mongodb v4+)本身已内置自动重连机制,无需手动轮询或封装重试逻辑——但前提是连接选项配置正确,且应用不意外销毁 MongoClient 实例。
为什么连接看起来“没重连”?常见错误现象
很多开发者反馈“断网后查不到数据”“抛出 ServerSelectionError”,其实不是驱动没重连,而是:
- 在每次请求时都新建
MongoClient(比如放在路由 handler 里),导致连接未复用、重连状态无法维持; - 没设置
serverSelectionTimeoutMS或设得太小(如 100ms),网络抖动时直接失败,根本等不到重连生效; - 监听了
close或error事件却调用了client.close(),主动终结了重连上下文; - 使用了过时的
reconnectTries/reconnectInterval(v4+ 已废弃,这些选项不再起作用)。
MongoClient 初始化必须全局单例 + 合理超时参数
连接对象应只创建一次,并在应用生命周期内复用。关键配置项直接影响重连行为:
const { MongoClient } = require('mongodb');
const client = new MongoClient('mongodb://localhost:27017', {
// 必须:让驱动等待更久再判定“选不到可用服务器”
serverSelectionTimeoutMS: 5000,
// 推荐:连接建立后,心跳检测间隔(默认10s,可缩短感知断连更快)
heartbeatFrequencyMS: 5000,
// 可选:连接池大小(默认100,高并发场景可调,但非重连关键)
maxPoolSize: 10,
// ⚠️ 禁用:不要设 connectTimeoutMS 过小(如 1000),否则首次连不上就失败
});
然后在启动时显式调用 client.connect(),并捕获初始化错误:
async function connectDB() {
try {
await client.connect();
console.log('MongoDB connected');
} catch (err) {
console.error('MongoDB connection failed:', err);
process.exit(1); // 启动失败应退出,而非静默重试
}
}
如何验证重连是否生效?真实场景下的行为
驱动的重连是后台异步进行的,你不需要也不应该手动触发。验证方式很简单:
- 启动应用并确认连接成功;
- 手动停掉 MongoDB(
sudo systemctl stop mongod); - 立刻执行一次
db.collection('test').findOne({})→ 会抛ServerSelectionError(因serverSelectionTimeoutMS到期); - 等待约 5–10 秒后重启 MongoDB;
- 再次查询 → 成功返回,且中间无代码干预。
注意:ServerSelectionError 不代表重连失败,只是当前操作超时;只要 MongoClient 实例活着,后台仍在尝试恢复连接。
需要手动干预的唯一情况:连接彻底不可恢复
极少数情况(如 DNS 变更、认证凭据失效、副本集 topology 完全不可达),驱动可能长期卡在 connecting 状态。此时可通过监听 topologyDescriptionChanged 事件观察状态变化:
client.on('topologyDescriptionChanged', (e) => {
if (e.newDescription.type === 'Unknown') {
console.warn('MongoDB topology lost, checking recovery...');
}
});
但依然不要在该事件里调用 client.close() 再新建实例——这会破坏内置重连。真正需要重建连接的场景,仅限于:应用明确收到运维通知要切换集群、或发生不可恢复的凭证错误(如 AuthenticationFailed)。
最常被忽略的一点:重连能力完全依赖 MongoClient 实例存活。只要你不把它赋值给局部变量、不重复 new、不主动 close,它就会一直尝试恢复连接——你写的每个 collection.findOne() 调用,底层都在用这个“活”的连接池。


















