Sequelize连接MariaDB超时错误捕获及NodeJS进程保活咨询
解决Sequelize连接MariaDB超时导致进程崩溃的问题
一、捕获错误,避免进程崩溃
- 全局监听未处理的Promise拒绝与异常
Node.js中未捕获的Promise拒绝或未处理的异常会直接终止进程,在应用入口添加全局监听:
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason); // 可在此添加告警逻辑,如发送通知 }); process.on('uncaughtException', (err) => { console.error('未捕获的异常:', err); // 必要时清理资源后触发进程退出,交由PM2重启 process.exit(1); });
- 监听Sequelize实例的错误事件
针对数据库连接类错误,直接在Sequelize实例上监听并处理:
const sequelize = new Sequelize(/* 你的配置 */); sequelize.on('error', (err) => { if (err.code === 'ERR_CONNECTION_TIMEOUT' || err.errno === 45012) { console.error('数据库连接超时,已捕获:', err); // 尝试重新建立连接 sequelize.authenticate().catch(reAuthErr => console.error('重新连接失败:', reAuthErr)); } else { console.error('数据库错误:', err); } });
- 数据库操作层添加try/catch包裹
所有Sequelize操作(查询、插入等)都用try/catch包裹,避免错误冒泡导致进程崩溃:
async function fetchData() { // 设置重试次数上限,避免无限循环 let retryCount = 0; const maxRetries = 3; while (retryCount < maxRetries) { try { return await Model.findOne({ where: /* 查询条件 */ }); } catch (err) { if (err.code === 'ERR_CONNECTION_TIMEOUT') { retryCount++; console.error(`查询超时,正在重试第${retryCount}次`); await new Promise(resolve => setTimeout(resolve, 1000)); } else { throw err; // 非超时错误可按需处理或向上抛出 } } } throw new Error('查询超时重试次数已达上限'); }
二、优化Sequelize连接配置,减少超时发生
调整连接池、超时时间与重试机制,降低超时概率:
const sequelize = new Sequelize("xxx", "xxx", "xxx", { host: "xxxx", dialect: "mariadb", pool: { max: 15, min: 2, // 保留最小连接数,避免频繁创建新连接 idle: 30000, // 延长空闲连接超时时间 acquire: 60000, // 获取连接的超时时间 evict: 10000 }, logging: false, timezone: "+01:00", dialectOptions: { connectTimeout: 5000, // 延长连接超时至5秒(默认1秒) keepAlive: true, // 开启TCP长连接 keepAliveInitialDelay: 30000 // 长连接初始延迟 }, retry: { max: 3, // 连接失败时的重试次数 match: [ /ETIMEDOUT/, /EHOSTUNREACH/, /ECONNRESET/, /ERR_CONNECTION_TIMEOUT/ ] // 指定需要重试的错误类型 } });
三、结合PM2增强稳定性
优化PM2配置文件(如ecosystem.config.js),确保进程崩溃后自动重启并留存日志:
module.exports = { apps: [{ name: 'your-app', script: 'app.js', instances: 'max', autorestart: true, // 进程崩溃自动重启 watch: false, max_memory_restart: '1G', log_date_format: 'YYYY-MM-DD HH:mm:ss', error_file: './logs/err.log', out_file: './logs/out.log', env: { NODE_ENV: 'production' } }] };
内容的提问来源于stack exchange,提问作者IFThenElse
相关产品推荐
相关产品推荐

