druid数据库连接池
为什么连接池数并不是越大越好?
第一点,首先我们要知道单核CPU“同时”运行多个线程,只不过是假象。单核CPU同一时刻只能执行一个线程,然后操作系统切换上下文,CPU 核心快速调度,执行另一个线程的代码。这其中便涉及到了大量上下文切换带来的额外性能损耗。
第二点,由上可知,一个N核心服务器,设置数据库连接数为N便能提供最优性能。然而,实际情况会受到磁盘IO和网络IO的影响,在IO等待时间内,线程阻塞等待,CPU处于空闲状态。因此,在线程处理I/O密集业务操作时,需要设置线程/连接数比CPU大一些,以提高吞吐量。
连接数的计算公式
连接数 = ((核心数 * 2) + 有效磁盘数)
服务器 CPU 是 4核 i7 的,连接池大小应该为 ((4 * 2) + 1) = 9 ~ 10个。具体需要根据实际业务场景做调整。
业务场景
对于并发访问,可以采用小的数据库连接池,然后将剩下的业务线程放在队列中等待。
如果系统中混合了长事务和短事务,正确的做法应该是创建两个连接池,一个服务于长事务,一个服务于"实时"查询,也就是短事务。
基本配置:
datasource:
url: jdbc:dm://127.0.0.1:5236/DMDB?zeroDateTimeBehavior=convertToNull
username: sysdba
password: sysdba@123456
driver-class-name: dm.jdbc.driver.DmDriver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 10
minIdle: 10
maxActive: 20
maxWait: 60000
# 多久进行一次连接是否空闲的检查;保证最小连接数的前提下,如果空闲时间超过minEvictableIdleTimeMillis则直接关闭
timeBetweenEvictionRunsMillis: 60000
# 一个连接的最大空闲时间, 查过这个空闲时间就会被关闭
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
# 设置从连接池获取连接时是否检查连接有效性,true时,每次都检查;false时,不检查
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500