Node.js应用出现MongooseServerSelectionError 30000ms服务器选择超时问题
Mongoose ServerSelectionTimeoutError 问题排查与解决方案
配置错误排查
- 开启
useUnifiedTopology: true后,auto_reconnect参数已被Mongoose 5.12.3版本废弃,不会生效,断线后无自动重连逻辑是运行一段时间后报错的核心常见原因。 poolSize: 50设置过大,若存在多应用实例/多进程部署,总连接数极易超过MongoDB服务端最大入站连接限制,导致连接耗尽。setMaxListeners(0)设置存在事件泄漏风险,未限制事件监听数会随连接异常逐步堆积。
对应MongoDB连接统计数据如下:
基础环境排查
- 网络连通性验证:在应用服务器执行
mongo "mongodb://username:password@ip:27017/dbname"直连测试,确认无防火墙、安全组、网络丢包问题。 - MongoDB服务端状态检查:登录实例查看CPU、内存、磁盘IO使用率,执行
db.currentOp()确认无慢查询阻塞连接池,执行db.serverStatus().connections查看当前连接数是否触达上限。 - 连接状态监控:在应用侧添加连接事件日志,监听
disconnected、error事件,确认报错触发时机是否和网络波动、服务端重启同步。
修复方案
连接配置修正
替换为兼容当前版本的有效配置,添加自动重连逻辑:
const mongoConnect = () => { return mongoose.connect("mongodb://username:password@ip:27017/dbname", { useUnifiedTopology: true, autoIndex: true, autoCreate: true, useFindAndModify: false, useNewUrlParser: true, useCreateIndex: true, socketTimeoutMS: 360000, connectTimeoutMS: 30000, maxPoolSize: 15, // 根据业务QPS调整,单进程建议10-20,总连接数不超过服务端限制的80% serverSelectionTimeoutMS: 30000, heartbeatFrequencyMS: 10000, }) } // 异常事件监听与重连逻辑 mongoose.connection.setMaxListeners(20) mongoose.connection.on('connected', () => { console.log('Mongoose connected successfully') }) mongoose.connection.on('error', (err) => { console.error('Mongoose connection error:', err) }) mongoose.connection.on('disconnected', () => { console.log('Mongoose disconnected, retrying connection after 5s') setTimeout(mongoConnect, 5000) }) // 首次初始化连接 mongoConnect()
额外优化建议
- 若使用MongoDB副本集,需在连接串中填写所有节点地址,避免单节点故障导致主节点选举失败。
- 调整操作系统TCP keepalive参数,
net.ipv4.tcp_keepalive_time设置为300,避免长连接被中间网络设备主动断开。 - 业务代码中避免未捕获的数据库操作异常导致连接挂起,所有数据库操作添加catch逻辑。
内容的提问来源于stack exchange,提问作者Yogendra Singh
相关产品推荐
相关产品推荐

