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:抽离全局连接池,复用单一实例
这是最关键的一步,把连接池的创建逻辑单独抽成一个模块,所有业务文件都复用这个单例:
- 创建一个单独的数据库配置文件,比如
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;
- 在所有业务文件里导入这个复用的连接池,而非重新创建:
// 任意业务文件 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
相关产品推荐
相关产品推荐

