1、简介
JAVA常用的连接池有dbcp、c3p0、tomcat-jdbc、Druid、HiKariCP。dbcp、c3p0、tomcat-jdbc 是第一代连接池,Druid和HiKariCP是第二代连接池, 第一代连接池一般采用单线程同步的架构设计,第二代采用多线程异步架构,目前的大部分工程会使用Druid或HiKariCP。
2、连接池
数据库连接池基于池化思想,实现了对连接资源灵活的管控。连接池本质是如何降低应用和数据库之间性能的消耗 。如果每次操作都需要打开连接和关闭连接,频繁的创建和销毁就会消耗大量的系统资源,从而降低系统性能。通过复用创建好的连接池连接,以避免频繁地为创建和销毁而增加的开销。
池化思想优点:
1.资源复用。
2.提升系统响应速度。
3.统一资源管理,避免数据库连接泄漏。
Druid连接池提供了监控功能,防SQL注入,密码加密,扩展性等。
3、性能比较
环境配置,在Windows 和Linux 不同操作系统测试结果可能存在一定误差。
msyql Version | 5.7.31 |
---|---|
Druid Version | 1.2.8 |
HikariCP Version | 4.0.3 |
JVM | -Xms2g -Xmx2g |
Windows | Intel® Core™ i7-10510U CPU @ 1.80GHz 2.30 GHz |
Springboot | 2.3.7.RELEASE |
测试工具 | SuperBenchmarker |
3.1、获取和关闭连接速度对比
一、使用JDBC驱动方式
sb -u http://127.0.0.1:8080/connection -c 10 -N 30 设置10个并发数及请求30秒。
public static Connection getConnection() throws SQLException {
Driver driver = new com.mysql.cj.jdbc.Driver();
Properties info = new Properties();
info.setProperty("user", USER_NAME);
info.setProperty("password", PASSWORD);
return driver.connect(DB_URL, info);
}
二、使用Druid连接池
sb -u http://127.0.0.1:8080/connection -c 10 -N 30 设置10个并发数及请求30秒。
static {
druidDataSource = new DruidDataSource();
druidDataSource.setUrl(DB_URL);
druidDataSource.setUsername(USER_NAME);
druidDataSource.setPassword(PASSWORD);
druidDataSource.setDriverClassName(JDBC_DRIVER);
}
public static Connection getConnection() throws SQLException {
return druidDataSource.getConnection();
}
三、使用HikariCP连接池
sb -u http://127.0.0.1:8080/connection -c 10 -N 30 设置10个并发数及请求30秒。
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(DB_URL);
config.setUsername(USER_NAME);
config.setPassword(PASSWORD);
config.setDriverClassName(JDBC_DRIVER);
hikariDataSource = new HikariDataSource(config);
}
public static Connection getConnection() throws SQLException {
return hikariDataSource.getConnection();
}
3.2、结论
获取和关闭连接速度
方式 | 请求数 | RPS(每秒请求数) |
---|---|---|
JDBC | 8479 | 272.9 |
Druid | 163898 | 5260.2 |
HikariCP | 156303 | 5008 |
获取和关闭Statement
方式 | 请求数 | RPS(每秒请求数) |
---|---|---|
JDBC | 6157 | 197.8 |
Druid | 48607 | 1556.5 |
HikariCP | 50182 | 1610.1 |
Jvisualvm监控
JDBC由于资源不能复用导致频繁的触发GC。
Druid触发2次GC
HikariCP触发了3次GC。
1、连接池没有进行任何参数优化的测试结果,获取Statement的获取和关闭HikariCP 略强于Druid,两者之间的性能差距很小。
2、Druid额外支持SQL监控,支持扩展,防止SQL注入等功能,后续会针对连接池进行参数的优化在做结果的对比。
3、使用Jvisualvm对堆内存监控可以发现如果频繁触发GC导致StopTheWorld 降低系统的吞吐量。
4 、常用的参数
参数 | 解释 |
---|---|
initialSize | 初始连接数 |
minIdle | 最小连接数 |
maxActive | 最大连接数 |
maxWait | 获取连接等待超时的时间 |
timeBetweenEvictionRunsMillis | 间隔多久检测一次空闲连接,太长可能会导致无法及时检测到连接中断,默认是60s |
keepAlive | 是否定期探活 |
keepAliveBetweenTimeMillis | 探活间隔时间 |
testWhileIdle | 获取连接池的连接空闲时间大于timeBetweenEvictionRunsMillis是否检查连接有效性,true检查: false不检查 |
testOnBorrow | 获取接时每次都验证有效性 |
testOnReturn | 连接使用后归连接验证有效性 |
minEvictableIdleTimeMillis | 连接在连接池中的最小生存时间 |
maxEvictableIdleTimeMillis | 连接在连接池中的最大生存时间 |
phyMaxUseCount | 连接最大使用次数,避免长时间使用相同连接造成服务器端负载不均衡 |
validConnectionChecker | 连接探活、有效性验证接口,使用使用mysqlPing或者查询SQL select 1 |