mysql中minidle_druid连接池的总量低于配置的minIdle
问题:我们线上配置的具体配置 minIdle=20,详情见附件1druid日志打印出来 activeCount+poolingCount=4 具体日志见附件2.连接池的总量已经低于最小值了。出现这种原因:业务从连接池获取连接后,testWhileIdle,发现连接失败(注:超过服务端空闲时间,已经被数据库服务端强行关闭,目前我们的运维体系里,服务端关闭被强行定义为15分钟)此时抛弃该连接,数量从初
问题:
我们线上配置的具体配置 minIdle=20,详情见附件1
druid日志打印出来 activeCount+poolingCount=4 具体日志见附件2.
连接池的总量已经低于最小值了。
出现这种原因:
业务从连接池获取连接后,testWhileIdle,发现连接失败(注:超过服务端空闲时间,已经被数据库服务端强行关闭,目前我们的运维体系里,服务端关闭被强行定义为15分钟)此时抛弃该连接,数量从初始值的20变为19.后面反复会陆续降低到业务真正使用的连接数,我们的业务上是4个。
进一步分析:
对于震荡式业务, 如果业务对连接数需求新增,会新建连接,连接池数量从4个增加到6个(在我们的业务场景下),然后业务需求降低,会有几个连接一直不被使用(连接池数据结构使用的数组堆栈),最终等到业务震荡高峰时被获取,如果刚好超过了minEvictableIdleTimeMillis并且已经被服务端关闭,testWhileIdle后被丢弃。
这个会导致连接池的意义被降低了,极端情况,对震荡式的业务会导致获取连接时会遇到 1.先testWhileIdle 2.再await等待CreateConnectionThread线程新建连接
代码分析和个人想法:
目前的CreateConnectionThread线程用于新建扩充,DestroyConnectionThread用于收缩:
看了源代码,我们是用的1.0.8 http://grepcode.com/file/repo1.maven.org/maven2/com.alibaba/druid/1.0.8/com/alibaba/druid/pool/DruidDataSource.java#DruidDataSource.shrink%28boolean%29
1. CreateConnectionThread 里面有这段代码
// 必须存在线程等待,才创建连接
if (poolingCount >= notEmptyWaitThreadCount) {
empty.await();
}
个人看法: 限制会不会太强了,虽然看上去较合理,但无法从4补全到20(minIdle配置值)的数量,失去了人工配置的minIdle意义,也无法很好的处理上面描述震荡式的的业务场景。
2. DestroyConnectionThread 里面shrink代码
final int checkCount = poolingCount - minIdle;
final long currentTimeMillis = System.currentTimeMillis();
for (int i = 0; i < checkCount; ++i) {
//闲置时间判断 和连接缩减
}
这里只对大于minIdle的连接进行缩减。
个人看法:是不是缺乏了对所有连接的test检查。场景:连接池配置超时时间是4个小时,mysql配置的是2个小时。目前代码会导致一些连接被服务端中断了,但是没有被有效关闭回收。
附件1:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.initialPoolSize=20
jdbc.minPoolSize=20
jdbc.maxPoolSize=50
jdbc.maxWaitTime=6000
jdbc.maxIdleTime=14400000
jdbc.acquireIncrement=5
jdbc.acquireCheckoutTimeout=3000
jdbc.idleConnectionTestPeriod=1800
mysql.driver.slave=com.mysql.jdbc.Driver
class="com.alibaba.druid.pool.DruidDataSource"init-method="init"
destroy-method="close">
value="20"/>
value="druid.stat.logSlowSql=true;druid.stat.slowSqlMillis=500;druid.stat.mergeSql=true"/>
附件2:
druid监控日志如下,{ "url": "jdbc:mysql:///dababase?characterEncoding=UTF-8",
"dbType": "mysql",
"name": "DataSource-4129454",
"activeCount": 0,
"activePeak": 4,
"activePeakTime": "2016-02-15 22:00:10",
"poolingCount": 4,
"poolingPeak": 4,
"poolingPeakTime": "2016-02-15 21:59:13",
"connectCount": 9354,
"closeCount": 9354,
"executeCount": 9962,
"errorCount": 1,
"commitCount": 305,
"pstmtCacheHitCount": 9956,
"pstmtCacheMissCount": 6,
"startTransactionCount": 305,
"transactionHistogram": [
0,
305
],
"connectionHoldTimeHistogram": [
8999,
353,
2
]
}
这个是druid打印的log日志
更多推荐
所有评论(0)