You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS Express应用如何处理MongoDB数据库连接丢失问题

优化方案

1. 全局监听MongoDB连接状态,启用自动重连

Mongoose本身提供了连接生命周期事件监听能力,不需要在每次数据库操作时单独判断连接错误。Mongoose 6+默认已经开启自动重连,你可以自定义重连策略,遇到断开事件只需要打日志即可,不需要直接终止进程,重连成功后会自动恢复数据库操作能力。

const mongoose = require('mongoose');
const { MongoNetworkError, MongooseServerSelectionError } = require('mongoose').Error;

// 连接配置,自定义重连参数
const mongoConnectOptions = {
  maxPoolSize: 10,
  serverSelectionTimeoutMS: 5000,
  socketTimeoutMS: 45000,
  // 自动重连相关配置,可按需调整
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 1000,
};

// 初始化连接
mongoose.connect(process.env.MONGO_URI, mongoConnectOptions);

// 全局监听连接事件
const db = mongoose.connection;
db.on('error', (err) => {
  if (err instanceof MongoNetworkError || err instanceof MongooseServerSelectionError) {
    console.error('Mongo | Mongoose 网络连接错误,将自动尝试重连', err.message);
  } else {
    console.error('MongoDB 连接错误', err);
  }
});
db.on('disconnected', () => console.warn('MongoDB 连接断开,正在尝试重连'));
db.on('reconnected', () => console.info('MongoDB 重连成功'));
db.on('connected', () => console.info('MongoDB 连接成功'));

2. 封装异步路由错误捕获中间件,统一处理异常

不用每个路由都编写重复的try/catch逻辑,用高阶函数包装所有异步路由处理器,自动捕获异常后传递给全局错误处理中间件即可。

// 异步路由错误捕获 wrapper
const asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

3. 全局错误处理中间件,统一拦截Mongo相关错误

所有路由抛出的错误都会走到该中间件,统一判断错误类型返回对应响应,不需要每个路由单独处理连接类错误。

// 注意错误处理中间件必须是4个参数,Express会自动识别
app.use((err, req, res, next) => {
  // 统一处理MongoDB连接相关错误
  if (err instanceof MongoNetworkError || err instanceof MongooseServerSelectionError) {
    console.error('请求处理过程中出现MongoDB网络错误', err.message);
    // 返回503服务不可用状态码,告知客户端稍后重试,不需要终止进程
    return res.status(503).json({
      code: 503,
      msg: '服务暂时不可用,请稍后重试'
    });
  }
  // 其他业务错误处理逻辑
  console.error('服务内部错误', err);
  res.status(500).json({ code: 500, msg: '服务内部错误' });
});

4. 优化后的路由写法

改造后路由不需要再写冗余的错误捕获和判断逻辑:

const registerCustomer = asyncHandler(async (req, res) => {
  const validRegistrationCode = await CustomerRegistrationCode.findOne({ code: req.body.code });
  return res.json({ obj: validRegistrationCode });
});

可选优化:添加连接状态预检中间件

如果需要在请求进入业务逻辑前就拦截断连场景,可以新增全局预检中间件:

app.use((req, res, next) => {
  // mongoose.connection.readyState取值:0=断开、1=已连接、2=连接中、3=断开中
  if (mongoose.connection.readyState !== 1) {
    return res.status(503).json({ code: 503, msg: '服务暂时不可用,请稍后重试' });
  }
  next();
});

注意:不建议遇到Mongo连接错误就直接调用process.exit(1)终止进程,Mongoose的自动重连机制会在网络恢复后自动重建连接,终止进程反而会导致服务完全不可用,需要人工重启才能恢复。

内容的提问来源于stack exchange,提问作者swftowu69

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 07:54:10