数据库连接池

数据库连接池基本概念

数据库连接池(Database Connection Pool)是一种用于管理数据库连接的技术,旨在提高数据库操作的性能和资源利用率。它通过预先创建并维护一定数量的数据库连接,避免频繁创建和关闭连接的开销,从而提升系统的响应速度和稳定性

为什么需要连接池

传统数据库连接的问题:

  1. 频繁创建和关闭连接
    • 每次执行 SQL 都需要创建连接,操作完成后关闭连接。
    • 创建和关闭连接是非常耗时的操作(涉及网络通信、身份验证等)。
  2. 资源浪费
    • 连接对象占用系统资源(如内存、CPU)。
    • 频繁创建和关闭连接会导致资源浪费。
  3. 性能瓶颈
    • 高并发场景下,频繁创建连接会导致数据库性能下降。
  4. 连接数限制
    • 数据库对同时打开的连接数有限制,频繁创建连接可能导致连接数耗尽

连接池的优势:

  1. 复用连接
    • 连接池预先创建一定数量的连接,应用程序从池中获取连接,使用完毕后归还连接。
  2. 减少开销
    • 避免了频繁创建和关闭连接的开销,提高了性能。
  3. 资源控制
    • 可以限制最大连接数,防止数据库连接数过多导致资源耗尽。
  4. 提高响应速度
    • 连接池中的连接是预先创建的,应用程序可以快速获取连接。

连接池的工作原理

核心组件:

  1. 连接池管理器
    • 负责创建、管理和销毁连接池。
  2. 连接池
    • 维护一组数据库连接,提供连接的获取和归还功能。
  3. 空闲连接
    • 当前未被使用的连接,存放在连接池中。
  4. 活动连接
    • 当前正在被使用的连接。

工作流程:

  1. 初始化连接池
    • 在应用程序启动时,连接池会预先创建一定数量的数据库连接。
  2. 获取连接
    • 应用程序从连接池中请求一个连接。
    • 如果池中有空闲连接,则直接返回;如果没有空闲连接且未达到最大连接数,则创建新连接;如果已达到最大连接数,则等待或抛出异常。
  3. 使用连接
    • 应用程序使用连接执行数据库操作。
  4. 归还连接
    • 操作完成后,应用程序将连接归还给连接池,而不是关闭连接。
  5. 连接回收
    • 连接池会定期检查连接的有效性,回收无效连接并创建新连接。

常见连接池实现

HikariCP

  • HikariCP 是一个高性能的 JDBC 连接池实现,以其轻量、快速和简单著称。它的设计目标是尽可能减少开销,提供最快的数据库连接获取速度

  • 特点

    • 轻量:代码量少,依赖少。
    • 高性能:在大多数场景下性能优于其他连接池。
    • 简单易用:配置简单,开箱即用。
    • 可靠性高:经过严格测试,稳定性强。
    • HikariCP 通过优化代码和减少锁竞争,显著提高了连接获取的速度
    • 减少了不必要的对象创建和垃圾回收,降低了 JVM 的开销
    • 自动维护连接池的健康状态,回收无效连接
  • 常用配置参数

    参数名 说明
    jdbcUrl 数据库连接 URL。
    username 数据库用户名。
    password 数据库密码。
    maximumPoolSize 连接池中允许的最大连接数,默认 10。
    minimumIdle 连接池中保持的最小空闲连接数,默认等于 maximumPoolSize。
    idleTimeout 连接空闲超时时间(毫秒),超过此时间未使用的连接会被回收,默认 600000(10 分钟)。
    maxLifetime 连接的最大生命周期(毫秒),超过此时间的连接会被回收,默认 1800000(30 分钟)。
    connectionTimeout 获取连接的超时时间(毫秒),默认 30000(30 秒)。
    poolName 连接池的名称,用于监控和日志记录。
  • 配置参数介绍

    • maximumPoolSize
      • 连接池中允许的最大连接数
        • 如果连接池中没有可用的空闲连接,且当前连接数已达到 maxPoolSize,连接池会让应用程序等待一段时间。
        • 等待时间由 maxWait 或 connectionTimeout 参数控制
        • 如果等待时间超过配置的超时时间,连接池会抛出异常(如 Druid:SQLException 或HikariCP: SQLTimeoutException
      • 数据库对同时打开的连接数有限制(如 MySQL 默认是 151),maxPoolSize 不应超过数据库的最大连接数
  • 使用示例

    • 添加依赖

      <dependency>
          <groupId>com.zaxxer</groupId>
          <artifactId>HikariCP</artifactId>
          <version>5.0.1</version>
      </dependency>
      
    • 配置连接池

      HikariConfig config = new HikariConfig();
      config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
      config.setUsername("root");
      config.setPassword("password");
      config.setMaximumPoolSize(20);
      config.setMinimumIdle(5);
      config.setIdleTimeout(300000); // 5 分钟
      config.setMaxLifetime(1800000); // 30 分钟
      config.setConnectionTimeout(30000); // 30 秒
      
      HikariDataSource dataSource = new HikariDataSource(config);
      
    • 使用连接池

      try (Connection connection = dataSource.getConnection()) {
          Statement stmt = connection.createStatement();
          ResultSet rs = stmt.executeQuery("SELECT * FROM users");
          while (rs.next()) {
              System.out.println(rs.getString("name"));
          }
      } catch (SQLException e) {
          e.printStackTrace();
      }
      
    • 监控与管理

      • HikariCP 提供了简单的监控接口,可以通过 HikariPoolMXBean 获取连接池的状态信息

        HikariPoolMXBean poolMXBean = dataSource.getHikariPoolMXBean();
        System.out.println("活动连接数: " + poolMXBean.getActiveConnections());
        System.out.println("空闲连接数: " + poolMXBean.getIdleConnections());
        System.out.println("总连接数: " + poolMXBean.getTotalConnections());
        

Druid

  • Druid 是阿里巴巴开源的数据库连接池实现,除了高性能外,还提供了丰富的监控和统计功能,适合需要深度监控和管理的场景

  • 特点

    • 高性能:性能接近 HikariCP。
    • 功能丰富:支持 SQL 监控、防火墙、加密等功能。
    • 监控强大:内置监控页面,支持实时查看连接池状态和 SQL 执行情况。
    • 扩展性强:支持自定义过滤器
  • 核心优势

    • SQL 监控
      • 可以监控 SQL 的执行时间、执行次数等,帮助优化 SQL 性能。
    • 防火墙功能
      • 提供 SQL 防火墙,防止恶意 SQL 注入。
    • 加密支持
      • 支持数据库密码加密,提高安全性。
    • 扩展性
      • 支持自定义过滤器,方便扩展功能
  • 配置参数

    参数名 说明
    url 数据库连接 URL。
    username 数据库用户名。
    password 数据库密码。
    maxActive 连接池中允许的最大连接数,默认 8。
    initialSize 连接池初始化时创建的连接数,默认 0。
    minIdle 连接池中保持的最小空闲连接数,默认 0。
    maxWait 获取连接的最大等待时间(毫秒),默认 -1(无限等待)。
    timeBetweenEvictionRunsMillis 连接回收线程的运行间隔时间(毫秒),默认 60000(1 分钟)。
    minEvictableIdleTimeMillis 连接在池中保持空闲的最小时间(毫秒),默认 1800000(30 分钟)。
    validationQuery 用于检测连接有效性的 SQL 语句,如 SELECT 1
  • 使用示例

    • 添加依赖

      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.2.8</version>
      </dependency>
      
    • 配置连接池

      DruidDataSource dataSource = new DruidDataSource();
      dataSource.setUrl("jdbc:mysql://localhost:3306/test");
      dataSource.setUsername("root");
      dataSource.setPassword("password");
      dataSource.setMaxActive(20);
      dataSource.setInitialSize(5);
      dataSource.setMinIdle(5);
      dataSource.setMaxWait(30000); // 30 秒
      dataSource.setTimeBetweenEvictionRunsMillis(60000); // 1 分钟
      dataSource.setMinEvictableIdleTimeMillis(1800000); // 30 分钟
      dataSource.setValidationQuery("SELECT 1");
      
    • 使用连接池

      try (Connection connection = dataSource.getConnection()) {
          Statement stmt = connection.createStatement();
          ResultSet rs = stmt.executeQuery("SELECT * FROM users");
          while (rs.next()) {
              System.out.println(rs.getString("name"));
          }
      } catch (SQLException e) {
          e.printStackTrace();
      }
      
    • 监控管理

      • Druid 提供了内置的监控页面,可以实时查看连接池的状态和 SQL 执行情况

      • 配置过滤器

        <bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter">
            <property name="slowSqlMillis" value="1000"/>
            <property name="logSlowSql" value="true"/>
        </bean>
        
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="filters" value="stat"/>
        </bean>
        
      • 启动应用后,访问 http://localhost:8080/druid 即可查看 Druid 的监控页面

HikariCP 与 Druid 的对比

特性 HikariCP Druid
性能 极高
功能 简单,专注于连接池 丰富,支持监控、防火墙等功能
监控 简单,通过 MXBean 获取状态 强大,内置监控页面
适用场景 高性能、轻量级应用 需要监控和管理的复杂应用
社区支持 活跃 活跃(阿里巴巴开源)
posted @ 2025-03-17 21:48  QAQ001  阅读(176)  评论(0)    收藏  举报