当前位置: 首页 > news >正文

HikariCP连接池使用和源码分析

HikariCP是一款高性能的JDBC连接池,凭借其卓越的性能和简洁的设计,成为了众多Java项目的首选连接池。本文将从使用方法、配置参数、架构设计和源码分析四个方面深入探讨HikariCP,帮助你全面掌握这一强大的工具。

一、HikariCP的使用方法与配置

1. 添加依赖

Maven项目中添加以下依赖:

<dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>5.0.0</version>
</dependency>

2. 基本配置与使用

以下是一个基本的HikariCP配置示例:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;public class HikariCPExample {public static void main(String[] args) {// 创建配置对象HikariConfig config = new HikariConfig();// 配置数据库连接信息config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");config.setUsername("root");config.setPassword("password");// 配置连接池参数config.setMaximumPoolSize(10);       // 最大连接数config.setMinimumIdle(5);            // 最小空闲连接数config.setConnectionTimeout(30000);  // 连接超时时间(毫秒)config.setIdleTimeout(600000);       // 空闲连接超时时间(毫秒)config.setMaxLifetime(1800000);      // 连接最大生命周期(毫秒)// 创建数据源HikariDataSource dataSource = new HikariDataSource(config);try (Connection connection = dataSource.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM users")) {while (resultSet.next()) {System.out.println("ID: " + resultSet.getInt("id") + ", Name: " + resultSet.getString("name"));}} catch (Exception e) {e.printStackTrace();} finally {// 关闭数据源dataSource.close();}}
}

3. 常用配置参数说明

参数名默认值说明
jdbcUrl-数据库连接URL
username-数据库用户名
password-数据库密码
maximumPoolSize10连接池最大连接数
minimumIdle与maximumPoolSize相同连接池保持的最小空闲连接数
connectionTimeout30000 (30秒)从连接池获取连接的超时时间
idleTimeout600000 (10分钟)空闲连接的超时时间,超时后连接会被关闭
maxLifetime1800000 (30分钟)连接的最大生命周期,超时后连接会被强制关闭
autoCommittrue是否自动提交事务
connectionTestQuery-连接测试SQL,用于验证连接的有效性
poolName“HikariPool-1”连接池名称,用于日志和JMX监控

二、HikariCP架构设计

HikariCP的架构设计遵循"Fast by Default"的原则,通过一系列优化实现了卓越的性能。其核心架构组件包括:

  1. HikariDataSource:数据源实现类,继承自javax.sql.DataSource,作为连接池的入口点。

  2. PoolBase:连接池的基础实现类,负责管理物理数据库连接,包括连接的创建、验证和销毁。

  3. HikariPool:连接池的核心实现,负责连接的池化管理,包括连接的获取、归还、空闲连接管理等。

  4. ProxyConnection:代理连接类,包装了实际的数据库连接,实现了连接的生命周期管理和性能监控。

  5. ConcurrentBag:HikariCP自定义的高性能并发对象池,用于存储和管理连接对象。

  6. HouseKeeper:后台线程,负责监控空闲连接和超时连接,定期清理和维护连接池。

HikariCP架构组件关系图:

┌─────────────────────┐
│    HikariDataSource   │
└───────────┬─────────┘│▼
┌─────────────────────┐
│      HikariPool       │
├─────────────────────┤
│ - ConcurrentBag      │
│ - HouseKeeper Thread │
└───────────┬─────────┘│▼
┌─────────────────────┐
│     PoolBase        │
├─────────────────────┤
│ - ConnectionFactory │
│ - ConnectionValidator │
└───────────┬─────────┘│▼
┌─────────────────────┐
│   ProxyConnection   │
└─────────────────────┘

三、HikariCP源码分析

1. 初始化过程

HikariCP的初始化过程主要在HikariPool类的构造函数中完成:

public HikariPool(final HikariConfig config) {super(config);this.config = config;this.connectionBag = new ConcurrentBag<>(this);this.suspendResumeLock = config.isAllowPoolSuspension() ? new SuspendResumeLock() : null;// 初始化连接池initializeConnections();
}

关键步骤包括:

  • 创建ConcurrentBag对象,用于存储连接
  • 根据配置参数初始化连接池,创建初始连接

2. 连接获取过程

当调用getConnection()方法时,实际执行的是HikariPoolgetConnection()方法:

public Connection getConnection(final long hardTimeout) throws SQLException {// 检查连接池状态suspendResumeLock.acquire();final long startTime = currentTime();try {long timeout = hardTimeout;do {// 从ConcurrentBag中获取连接PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);if (poolEntry == null) {break; // 超时,返回null}final long now = currentTime();// 检查连接是否超时或无效if (poolEntry.isMarkedEvicted() || (elapsedMillis(poolEntry.lastAccessed, now) > aliveBypassWindowMs && !isConnectionAlive(poolEntry.connection))) {closeConnection(poolEntry, poolEntry.isMarkedEvicted() ? EVICTED_CONNECTION_MESSAGE : DEAD_CONNECTION_MESSAGE);timeout = hardTimeout - elapsedMillis(startTime, now);} else {// 连接有效,返回代理连接metricsTracker.recordBorrowStats(poolEntry, startTime);return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry), now);}} while (timeout > 0L);// 超时处理metricsTracker.recordBorrowTimeoutStats(startTime);throw createTimeoutException(startTime);} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new SQLException(poolName + " - Interrupted during connection acquisition", e);} finally {suspendResumeLock.release();}
}

连接获取的核心逻辑:

  • ConcurrentBag中借用连接对象
  • 检查连接的有效性和生命周期
  • 返回包装了实际连接的代理对象ProxyConnection

3. ConcurrentBag高性能实现

ConcurrentBag是HikariCP的核心组件之一,它采用了一种高效的无锁算法来管理对象池:

public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseable {private final CopyOnWriteArrayList<T> sharedList;private final ThreadLocal<List<Object>> threadList;private final AtomicInteger waiters;private final SynchronousQueue<T> handoffQueue;private final IBagStateListener listener;// ... 其他成员变量和方法
}

ConcurrentBag的主要特点:

  • 使用CopyOnWriteArrayList存储共享对象
  • 为每个线程维护一个ThreadLocal列表,减少线程间竞争
  • 使用SynchronousQueue实现高效的线程间对象传递
  • 通过IBagStateListener监听连接池状态变化

4. 连接验证与回收

HikariCP通过HouseKeeper线程定期检查和维护连接池:

private final class HouseKeeper implements Runnable {@Overridepublic void run() {try {// 刷新统计信息connectionTimeoutStats.reset();// 检查是否需要收缩连接池final List<PoolEntry> notInUse = connectionBag.values(STATE_NOT_IN_USE);int toRemove = notInUse.size() - config.getMinimumIdle();for (PoolEntry entry : notInUse) {if (toRemove > 0 && entry != null && (currentTime() - entry.lastAccessed) > idleTimeout) {if (connectionBag.reserve(entry)) {closeConnection(entry, "(connection has passed idleTimeout)");toRemove--;}}}// 标记需要淘汰的连接softEvictConnections();// 检查连接池状态if (getTotalConnections() < config.getMinimumIdle()) {fillPool(); // 添加新连接}} catch (Exception e) {logger.error("Unexpected exception in housekeeping task", e);}}
}

HouseKeeper线程的主要职责:

  • 清理空闲时间超过idleTimeout的连接
  • 标记并淘汰超过maxLifetime的连接
  • 确保连接池中的连接数量保持在minimumIdle以上

四、HikariCP性能优化策略

HikariCP之所以能在众多连接池中脱颖而出,主要得益于以下优化策略:

  1. 字节码优化:使用Java字节码生成技术(如Byte Buddy)创建轻量级的代理对象,减少代理开销。

  2. 无锁设计:通过ConcurrentBag实现无锁算法,减少线程间竞争,提高并发性能。

  3. 最小化同步范围:在关键代码路径上减少锁的使用,只在必要时进行同步。

  4. 优化的连接验证:使用高效的连接验证机制,避免不必要的数据库查询。

  5. 预编译语句缓存:内置Statement缓存,减少SQL预编译开销。

  6. 零分配设计:在核心代码路径上避免创建临时对象,减少GC压力。

五、总结

HikariCP凭借其卓越的性能和简洁的设计,成为了现代Java应用中首选的数据库连接池。通过深入理解其使用方法、配置参数、架构设计和源码实现,我们可以更好地在项目中应用和优化HikariCP,提高数据库访问性能。

主要关键点:

  • 使用简单:通过HikariConfig配置连接池参数,通过HikariDataSource获取连接
  • 配置灵活:提供丰富的配置参数,满足各种场景需求
  • 架构高效:采用分层设计,核心组件职责明确
  • 性能卓越:通过多种优化策略实现高性能
  • 源码精妙:深入学习其源码可以了解到许多高性能编程技巧

在实际项目中,建议根据应用的负载特性和数据库特点,合理调整HikariCP的配置参数,以达到最佳性能。

相关文章:

  • NB-IoT NPUSCH(三)-资源映射
  • 一种C# 的SM4 的 加解密的实现,一般用于医疗或者支付
  • 多线程(1)
  • ODSA架构与操作-1
  • 2025最新Gemini 2.5 Pro API限制全面解析:最完整的使用指南与优化方案
  • 做好测试用例设计工作的关键是什么?
  • 仓颉入门:特性
  • 嵌入式自学第二十九天(5.27)
  • DFS入门刷题c++
  • AI 智能体的那些事—架构设计关键点
  • 数据库管理与高可用-MySQL数据库初体验
  • Java 内存模型与 volatile 关键字深度解析:从可见性到指令重排
  • 【键盘说明书备份】ENERGYFORT
  • 什么是舵机,如何控制舵机
  • LVGL(Grid)
  • 用Qt/C++玩转观察者模式:一个会聊天的设计模式
  • Baklib企业CMS实现内容智能归档与精准检索
  • 红黑树,B树,二叉树之间的不同
  • C++类继承详解:权限控制与继承方式解析
  • Gemini Pro 2.5 输出
  • 无锡企业网站制作公司有哪些/chatgpt中文在线
  • wordpress ajax顶踩/seo搜索引擎是什么
  • linux中怎么打开wordpress/微软优化大师
  • 什么游戏可以赚钱真实可靠/家居seo整站优化方案
  • 店铺装修设计网站/百度推广有效果吗?
  • 上海有哪些网络公司/seo的优点和缺点