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

如何正确处理Node.js中的ECONNRESET错误?已修复PROTOCOL_CONNECTION_LOST

问题分析与解决方案

为什么ECONNRESET错误没被解决?

你的错误处理逻辑里虽然捕获了ECONNRESET并调用handleDisconnect,但大概率是handleDisconnect的实现存在缺陷:

  • 没有彻底清理旧连接的残留资源(比如未完成的查询、绑定的事件)
  • 重建连接后,未重新绑定所有必要的事件监听
  • 连接断开重建期间,定时器仍在执行,导致多次触发错误或连接冲突

优化方案

1. 放弃单连接,改用MySQL连接池

单长连接极易因MySQL端超时、网络波动等原因断开,连接池会自动管理连接的创建、复用与销毁,遇到失效连接会自动重建,是更稳定的方案。示例代码:

const mysql = require('mysql2/promise');
// 创建连接池
const pool = mysql.createPool({
  host: '你的数据库地址',
  user: '用户名',
  password: '密码',
  database: '数据库名',
  connectionLimit: 5, // 根据业务量调整连接数
  waitForConnections: true
});

// 封装插入函数
async function insertData(generatedValue) {
  let conn;
  try {
    conn = await pool.getConnection();
    await conn.execute('INSERT INTO 表名 (字段名) VALUES (?)', [generatedValue]);
  } catch (err) {
    console.error('插入失败:', err);
    // 连接类错误由连接池自动处理,无需手动重建
    if ([ 'ECONNRESET', 'PROTOCOL_CONNECTION_LOST' ].includes(err.code)) {
      console.log('连接异常,连接池将自动重建');
    }
  } finally {
    if (conn) conn.release(); // 释放连接回池
  }
}

// 定时器逻辑
setInterval(async () => {
  try {
    const value = Math.random(); // 替换成你的值生成逻辑
    await insertData(value);
    // WebSocket推送逻辑...
  } catch (wsErr) {
    console.error('推送失败:', wsErr);
  }
}, 1000);

2. 捕获定时器中的所有异步错误

setInterval的异步回调如果抛出未捕获错误,会直接导致进程崩溃。必须在回调内部添加try-catch,避免未处理的异常扩散。

3. 检查MySQL服务器超时配置

查看MySQL的wait_timeout和interactive_timeout参数,这两个参数控制连接的空闲超时时间,若值过短,MySQL会主动断开空闲连接。可通过以下SQL查询:

SHOW VARIABLES LIKE '%timeout';

如需调整,可在MySQL配置文件中修改(比如设置为20小时):

wait_timeout = 72000
interactive_timeout = 72000

注意:这只是辅助手段,核心解决方案还是使用连接池。

4. 完善handleDisconnect(若坚持用单连接)

如果一定要用单连接,需确保handleDisconnect能彻底重建连接并恢复业务逻辑:

function handleDisconnect() {
  // 销毁旧连接
  if (connection) {
    connection.destroy();
  }
  // 重新创建连接
  connection = mysql.createConnection({ /* 你的连接配置 */ });
  connection.connect(err => {
    if (err) {
      console.error('重连失败,1秒后重试:', err);
      setTimeout(handleDisconnect, 1000);
      return;
    }
    console.log('数据库重连成功');
    // 重新绑定错误事件
    connection.on('error', function(err) {
      console.log('db error', err);
      if(err.code === 'PROTOCOL_CONNECTION_LOST' || err.code === 'ECONNRESET') {
        handleDisconnect();
      } else {
        throw err;
      }
    });
  });
}

注意:这种方式下,重连期间的数据库操作会失败,需额外添加重试逻辑,否则会丢失数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:05:58