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

Node.js MySQL生产环境频繁出现errno:-104(ECONNRESET)错误求助

Node.js + MySQL 频繁出现 ECONNRESET 错误的排查与解决

ECONNRESET 错误本质是TCP连接被MySQL服务器主动重置,通常是连接超时、资源不足或网络问题导致的,以下是具体的排查方向和解决建议:

一、检查MySQL服务器配置

  • 空闲连接超时设置:查看wait_timeout和interactive_timeout参数,这两个值控制MySQL自动断开空闲连接的时间。如果Node.js的连接空闲时间超过这个阈值,就会触发连接重置。执行以下命令查看:
    SHOW VARIABLES LIKE '%timeout%';
    
    根据业务场景调整(比如设置为3600秒),修改时可以在MySQL配置文件(my.cnf或my.ini)中添加:
    wait_timeout = 3600
    interactive_timeout = 3600
    
    重启MySQL生效。
  • 连接数上限:检查max_connections是否达到上限,导致新连接被拒绝。执行:
    SHOW VARIABLES LIKE 'max_connections';
    SHOW STATUS LIKE 'Threads_connected';
    
    如果当前连接数接近上限,要么调大max_connections,要么优化Node.js的连接池配置减少并发连接。
  • 查看MySQL错误日志:在Linux系统通常是/var/log/mysql/error.log,Windows则在MySQL安装目录的data文件夹下。查找Aborted connection相关日志,能直接看到连接断开的具体原因。

二、优化Node.js客户端配置

  • 正确使用连接池并监听错误:如果用的是连接池,必须监听error事件,防止未捕获错误导致进程崩溃。示例配置:
    const mysql = require('mysql'); // 建议替换为mysql2
    const pool = mysql.createPool({
      host: '你的MySQL地址',
      user: '用户名',
      password: '密码',
      database: '数据库名',
      connectionLimit: 10, // 不要超过MySQL的max_connections
      waitForConnections: true,
      queueLimit: 0
    });
    
    // 关键:监听连接池错误,避免进程退出
    pool.on('error', (err) => {
      console.error('连接池错误:', err);
      // ECONNRESET错误通常是连接已断开,连接池会自动重建连接,无需额外处理
    });
    
  • 单个连接的错误处理:如果没有用连接池,手动创建的连接必须监听error事件,断开时自动重建:
    let connection;
    
    function initConnection() {
      connection = mysql.createConnection({ /* 配置 */ });
      connection.connect((err) => {
        if (err) {
          console.error('连接失败,2秒后重试:', err);
          setTimeout(initConnection, 2000);
          return;
        }
        connection.on('error', (err) => {
          console.error('连接出错:', err);
          if (err.fatal) {
            initConnection(); // 致命错误,重建连接
          }
        });
      });
    }
    
    initConnection();
    
  • 升级到mysql2模块:你当前使用的mysql模块已停止维护,mysql2是其继任者,修复了大量连接相关的bug,性能也更好。安装命令:
    npm install mysql2
    
    代码中只需替换require('mysql')为require('mysql2'),API基本兼容。

三、排查网络问题

  • 测试连通性:在Node.js服务器上用ping <MySQL主机>检查是否有丢包,用telnet <MySQL主机> 3306测试端口是否能正常访问,确认没有防火墙或负载均衡器拦截连接。
  • 调整TCP保活配置:Linux系统默认的TCP保活时间是7200秒,太长可能导致MySQL断开连接后Node.js无法及时感知。临时调整:
    echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
    
    永久生效则编辑/etc/sysctl.conf,添加:
    net.ipv4.tcp_keepalive_time = 300
    
    执行sysctl -p生效。

四、代码层面最佳实践

  • 避免长期持有单个连接:优先使用连接池,它会自动管理连接的复用和销毁,减少连接断开的概率。
  • 捕获所有查询错误:每个数据库查询都要处理错误,必要时添加重试逻辑:
    function queryWithRetry(sql, params, callback) {
      pool.query(sql, params, (err, results) => {
        if (err && err.code === 'ECONNRESET') {
          // 重试一次
          pool.query(sql, params, callback);
          return;
        }
        callback(err, results);
      });
    }
    
    // 使用示例
    queryWithRetry('INSERT INTO bookings SET ?', { user_id: 1, time: new Date() }, (err, res) => {
      if (err) {
        console.error('预订失败:', err);
        return;
      }
      console.log('预订成功');
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:01:03