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全面教学】MySQL备份与恢复Day14(2026年)
数据库·后端·mysql
Asmewill5 分钟前
DeepAgents学习笔记三(Backend记忆存储)
前端
渣渣盟7 分钟前
MySQL DDL操作全解析:从入门到精通,包含索引视图分区表等全操作解析
大数据·数据库·mysql
Alan Lu Pop21 分钟前
前端开发助手
前端·智能体
程序员鱼皮22 分钟前
我用 GitHub 仓库养 AI 龙虾,自动开发上线项目!保姆级教程
前端·人工智能·ai·程序员·github·编程·ai编程
mN9B2uk1728 分钟前
为mysql数据库建立索引
数据库·mysql·oracle
流星白龙35 分钟前
【MySQL高阶】7.MySQL日志
数据库·mysql·adb
276695829235 分钟前
京东随机变速滑块拼图验证码识别(京东E卡)
java·服务器·前端·python·京东滑块·京东变速滑块·京东e卡绑卡
Irene199140 分钟前
SQL示例:正确理解题意(隐藏分组键)严格SQL模式下,ORDER BY中的列必须出现在GROUP BY中或作为聚合函数
mysql
流星白龙1 小时前
【MySQL高阶】0.MySQL的安装
数据库·mysql·adb