mysql2连接池配置与优化

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: 连接池最大连接数,默认10
  • queueLimit: 等待队列的最大请求数,0表示无限制
  • waitForConnections: 当无可用连接时是否等待,默认true

性能优化参数

  • idleTimeout: 连接空闲超时时间(毫秒),默认60000
  • maxIdle: 最大空闲连接数,默认与connectionLimit相同
  • enableKeepAlive: 保持连接活性,默认false
  • keepAliveInitialDelay: 保持连接初始延迟(毫秒),默认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数据库连接池实现。实际应用中应根据具体业务场景和负载特点进行调整。

相关推荐
数据蜂巢2 小时前
MySQL 8.0 生产环境备份脚本 (Percona XtraBackup 8.0+)
android·mysql·adb
PorkCanteen2 小时前
Cursor使用-从问题到解决方案(以及一些通用rules)
前端·ai·ai编程
小马_xiaoen2 小时前
Promise 从入门到精通:彻底解决前端异步回调问题!!!
前端·javascript
jingling5552 小时前
uniapp | 基于高德地图实现位置选择功能(安卓端)
android·前端·javascript·uni-app
某公司摸鱼前端2 小时前
前端一键部署网站至服务器FTP
前端·javascript·uni-app
m0_647057962 小时前
uniapp使用rich-text流式 Markdown 换行问题与解决方案
前端·javascript·uni-app
yangSnowy2 小时前
MySQL 分布式锁实现方案
数据库·分布式·mysql
We་ct2 小时前
LeetCode 49. 字母异位词分组:经典哈希解法解析+易错点规避
前端·算法·leetcode·typescript·哈希算法
CHU7290353 小时前
废品回收小程序前端功能设计逻辑与实践
前端·小程序