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数据库连接池实现。实际应用中应根据具体业务场景和负载特点进行调整。

相关推荐
掘金一周8 小时前
吃龙虾🦞咯!万字拆解OpenClaw的架构与设计 | 掘金一周 3.19
前端·人工智能·后端
kyriewen8 小时前
JavaScript 数据类型全家福:谁是大哥大,谁是小透明?
前端·javascript·ecmascript 6
用户8631263327688 小时前
假设我要实现一个agent群体
前端
console.log('npc')8 小时前
pnpm使用
前端·npm
grizzliesster28 小时前
MySQL——表的约束
数据库·mysql
OpenTiny社区8 小时前
TinyRobot Skills技巧大公开:让 AI 成为你的 “UI 搭建”副驾驶
前端·vue.js·ai编程
土豆12509 小时前
Rust 实战:手把手教你开发一个命令行工具
前端·rust
Moment9 小时前
2026年,TypeScript还值不值得学 ❓❓❓
前端·javascript·面试
林九生9 小时前
【Vue3】解决 Tailwind CSS v4 + Vite 8 中 `@import “tailwindcss“` 不起作用的问题
前端·css
陈随易9 小时前
AI时代,说点心里话
前端·后端·程序员