removeAbandoned实际上就是Druid的泄露检测机制。removeAbandoned作为开启连接泄露检测机制的开关,默认为false,当为true的时候,在随着DestroyTask的调用频率定期检测。主要的参数有:
removeAbandoned | 如果连接泄露,是否需要回收泄露的连接,默认false; | spring.datasource.druid.removeAbandoned=true |
logAbandoned | 如果回收了泄露的连接,是否要打印一条log,默认false; |
removeAbandonedTimeoutMillis | 连接回收的超时时间,默认5分钟; | spring.datasource.druid.removeAbandonedTimeout=300000 |
异常问题
org.apache.ibatis.exceptions.PersistenceException:
### Error rolling back transaction. Cause: java.sql.SQLException: connection closed
### Cause: java.sql.SQLException: connection closed
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.rollback(DefaultSqlSession.java:240)
at org.apache.ibatis.session.defaults.DefaultSqlSession.rollback(DefaultSqlSession.java:231)
at com.istrong.ec.dao.MybatisSqlDao.rollback(MybatisSqlDao.java:80)
... ...
at java.lang.Thread.run(Thread.java:750)
Caused by: java.sql.SQLException: connection closed
at com.alibaba.druid.pool.DruidPooledConnection.checkStateInternal(DruidPooledConnection.java:1190)
at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1181)
at com.alibaba.druid.pool.DruidPooledConnection.getAutoCommit(DruidPooledConnection.java:769)
at org.apache.ibatis.transaction.jdbc.JdbcTransaction.rollback(JdbcTransaction.java:78)
at org.apache.ibatis.executor.BaseExecutor.rollback(BaseExecutor.java:256)
at org.apache.ibatis.executor.CachingExecutor.rollback(CachingExecutor.java:126)
at org.apache.ibatis.session.defaults.DefaultSqlSession.rollback(DefaultSqlSession.java:237)
... 6 more
解决处理
spring: datasource: dynamic: druid: remove-abandoned: true remove-abandoned-timeout-millis: 300000
spring:
datasource:
dynamic:
druid:
fail-fast: true
# 配置监控统计拦截的filters
filters: slf4j,stat
# 配置从连接池获取连接等待超时的时间
max-wait: 2000
# 5.7之后支持游标,是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大;
pool-prepared-statements: false
query-timeout:
# 连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行,如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中
remove-abandoned: true
# 检查连接泄露依据(超时时间)removeAbandonedTimeoutMillis(默认5分钟):连接回收的超时时间;设置了removeAbandoned为true,Druid会定期检查线程池溢出的情况,如果不是运行状态,且超过设置的时间就会被回收;
remove-abandoned-timeout-millis: 300000
slf4j:
enable: true
statement-executable-sql-log-enable: true
# testOnBorrow(默认true):建议配置为false,申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
test-on-borrow: false
# testOnReturn(默认false):建议配置为false,归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能;
test-on-return: false
# testWhileIdle(默认false)是一个检测配置项:建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效;
test-while-idle: true
# 创建initialSize个连接
initial-size: 8
# 线程池中最大连接数
max-active: 30
# minIdle:线程池最小空闲数,Druid会定期扫描连接数情况,如果扫描的值大于该值就关闭多余的连接数,小于就创建符合要求的连接数;这个参数的主要用处是突然有大量的请求的时候,就会创建新的连接数,这是个比较耗时的操作;
min-idle: 5
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 180000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
其他附件
Druid源码阅读8-DruidDataSource的removeAbandoned机制