MySQL2 连接池配置与优化
MySQL2 是一个流行的 Node.js MySQL 客户端,支持连接池功能。连接池可以显著提升数据库性能,减少频繁创建和销毁连接的开销。
安装 MySQL2
bash
npm install mysql2
基本连接池配置
javascript
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
连接池关键参数详解
核心参数
connectionLimit: 连接池最大连接数,默认10queueLimit: 等待队列的最大请求数,0表示无限制waitForConnections: 当无可用连接时是否等待,默认true
性能优化参数
idleTimeout: 连接空闲超时时间(毫秒),默认60000maxIdle: 最大空闲连接数,默认与connectionLimit相同enableKeepAlive: 保持连接活性,默认falsekeepAliveInitialDelay: 保持连接初始延迟(毫秒),默认0
高级优化策略
连接验证配置
javascript
createPool({
// ...其他配置
testOnBorrow: true,
validationQuery: 'SELECT 1'
});
超时控制
javascript
createPool({
// ...其他配置
connectTimeout: 10000,
acquireTimeout: 10000
});
SSL连接配置
javascript
createPool({
// ...其他配置
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync(__dirname + '/mysql-ca.crt')
}
});
连接池封装实践
基础封装示例
javascript
class Database {
constructor(config) {
this.pool = mysql.createPool({
...config,
connectionLimit: config.connectionLimit || 10,
waitForConnections: true
});
}
async query(sql, params) {
const [rows] = await this.pool.query(sql, params);
return rows;
}
async transaction(callback) {
const conn = await this.pool.getConnection();
try {
await conn.beginTransaction();
const result = await callback(conn);
await conn.commit();
return result;
} catch (err) {
await conn.rollback();
throw err;
} finally {
conn.release();
}
}
}
高级封装方案
javascript
class AdvancedDB {
constructor(config) {
this.config = {
connectionLimit: 20,
idleTimeout: 30000,
...config
};
this.initPool();
}
initPool() {
this.pool = mysql.createPool(this.config);
this.pool.on('connection', (conn) => {
console.log('New connection established');
});
this.pool.on('acquire', (conn) => {
console.log('Connection acquired');
});
}
async execute(sql, params, conn) {
const executor = conn || this.pool;
try {
const [rows] = await executor.query(sql, params);
return rows;
} catch (err) {
console.error('Query failed:', err);
throw err;
}
}
async withTransaction(fn) {
const conn = await this.pool.getConnection();
try {
await conn.beginTransaction();
const result = await fn(conn);
await conn.commit();
return result;
} catch (err) {
await conn.rollback();
throw err;
} finally {
conn.release();
}
}
async close() {
await this.pool.end();
}
}
性能监控与调优
连接池状态监控
javascript
// 定期检查连接池状态
setInterval(() => {
console.log(`Active connections: ${pool._allConnections.length}`);
console.log(`Idle connections: ${pool._freeConnections.length}`);
console.log(`Waiting acquire: ${pool._acquiringConnections.length}`);
}, 5000);
动态调整参数
javascript
// 根据负载动态调整连接池大小
function adjustPoolSize() {
const load = getSystemLoad();
if (load > 0.7) {
pool.config.connectionLimit = Math.min(50, pool.config.connectionLimit + 5);
} else {
pool.config.connectionLimit = Math.max(10, pool.config.connectionLimit - 2);
}
}
最佳实践建议
连接池大小计算
- 公式:
连接数 = (核心数 * 2) + 有效磁盘数 - 对于CPU密集型应用可减少连接数
- 对于I/O密集型应用可增加连接数
连接泄漏防护
javascript
// 使用AsyncResource跟踪连接
const { AsyncResource } = require('async_hooks');
class TrackedConnection {
constructor(conn) {
this.resource = new AsyncResource('DBConnection');
this.conn = conn;
}
query(sql, params) {
return this.resource.runInAsyncScope(() => {
return this.conn.query(sql, params);
});
}
}
连接预热策略
javascript
// 应用启动时预热连接池
async function warmupPool(pool, count) {
const connections = [];
for (let i = 0; i < count; i++) {
connections.push(pool.getConnection());
}
await Promise.all(connections);
connections.forEach(conn => conn.release());
}
错误处理模式
重试机制实现
javascript
async function queryWithRetry(sql, params, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await pool.query(sql, params);
} catch (err) {
if (i === retries - 1 || !isRetryableError(err)) throw err;
await delay(100 * (i + 1));
}
}
}
function isRetryableError(err) {
return err.code === 'ECONNRESET' ||
err.code === 'ETIMEDOUT' ||
err.code === 'PROTOCOL_SEQUENCE_TIMEOUT';
}
这些配置和优化策略可以帮助构建高性能、可靠的MySQL数据库连接池实现。实际应用中应根据具体业务场景和负载特点进行调整。