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

Node.js连接MySQL出现ER_CON_COUNT_ERROR: Too many connections错误

解决Node.js中MySQL连接池导致的ER_CON_COUNT_ERROR错误

嘿,这个问题我之前帮不少开发者踩过坑,本质上是你现在的写法踩了「重复创建连接池」的雷——20个Node.js文件各自创建独立的连接池,每个池都会建立自己的连接组,叠加起来直接超出MySQL的最大连接数限制了。咱们一步步来搞定它:

核心问题拆解

你每个文件里都调用mysql.createPool(),相当于在系统里开了20个完全独立的连接池。默认情况下每个连接池的connectionLimit是10,算下来20*10=200,很容易超过MySQL默认的max_connections(通常是151),自然就触发ER_CON_COUNT_ERROR了。


解决方案1:抽离全局连接池,复用单一实例

这是最关键的一步,把连接池的创建逻辑单独抽成一个模块,所有业务文件都复用这个单例:

  1. 创建一个单独的数据库配置文件,比如db.js:
// db.js
const mysql = require('mysql');

// 只在这里创建一次连接池,全局复用
const pool = mysql.createPool({
  host: databaseHost,
  user: databaseUser,
  password: databasePassword,
  database: databaseName,
  multipleStatements: true,
  // 可根据业务和MySQL配置调整连接池参数
  connectionLimit: 10, // 控制单池最大连接数,别超过MySQL的max_connections
  waitForConnections: true, // 无可用连接时排队等待,而非直接报错
  queueLimit: 0 // 排队请求无限制(按需调整)
});

module.exports = pool;
  1. 在所有业务文件里导入这个复用的连接池,而非重新创建:
// 任意业务文件
const pool = require('./db.js'); // 路径根据你的项目结构调整

// 正常使用getConnection逻辑
pool.getConnection(function (err, connection) {
  if (err) {
    return callback(err);
  }
  
  const sql = "...sql statement...";
  const inserts = [...inserts...];
  
  connection.query(sql, inserts, function (error, results) {
    // 无论查询成功/失败,务必释放连接回池!
    connection.release();
    if (error) {
      return callback(error);
    }
    callback(null, results);
  });
});

解决方案2:确保连接被正确释放

很多时候连接数超限,是因为忘记释放连接导致连接被永久占用。一定要保证在查询完成(无论成功失败)后调用connection.release(),也可以用try/finally或者Promise语法来强制保证:

用Promise+async/await优化(更易维护)

const util = require('util');
const pool = require('./db.js');
// 把回调风格的方法转成Promise
const getConnection = util.promisify(pool.getConnection).bind(pool);

async function fetchData() {
  let connection;
  try {
    connection = await getConnection();
    const query = util.promisify(connection.query).bind(connection);
    const results = await query("SELECT * FROM your_table WHERE id = ?", [123]);
    return results;
  } catch (err) {
    throw err;
  } finally {
    // 无论如何都会执行,确保连接释放
    if (connection) connection.release();
  }
}

解决方案3:按需调整MySQL最大连接数(可选)

如果业务确实需要更多连接,可以修改MySQL的配置文件(比如my.cnf或my.ini):

[mysqld]
max_connections = 200 # 根据服务器CPU、内存资源调整,别盲目调大

修改后重启MySQL服务,但这只是治标手段,核心还是复用连接池+正确释放连接。


额外技巧:监控连接池状态

可以给连接池加事件监听,方便排查连接泄漏问题:

// 在db.js里添加监听
pool.on('acquire', (connection) => {
  console.log(`连接 ${connection.threadId} 被占用`);
});

pool.on('release', (connection) => {
  console.log(`连接 ${connection.threadId} 已释放`);
});

pool.on('enqueue', () => {
  console.log("等待可用连接中...");
});

总的来说,只要搞定「单一连接池复用」和「连接正确释放」这两点,这个连接数超限的问题就能彻底解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:43:44