dbcp配置浅谈

来源:互联网 发布:windows escape python 编辑:程序博客网 时间:2024/05/29 14:50

最近做一个项目,在配置mybatis后,访问一段时间接着再访问时遇到了这么一个异常。

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

具体的就是下面这些参数的问题。这是dbcp官网中的说明,不过是英语翻译就免了,细细分析下。

其中的一些指的是在dbcp中的默认值。
validationQuery The SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query MUST be an SQL SELECT statement that returns at least one row.


testOnBorrow true  The indication of whether objects will be validated before being borrowed from the pool. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.
NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.


testOnReturn falseThe indication of whether objects will be validated before being returned to the pool. 
NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.


testWhileIdle   falseThe indication of whether objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool. 
NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string.


timeBetweenEvictionRunsMillis -1The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.


numTestsPerEvictionRun 3The number of objects to examine during each run of the idle object evictor thread (if any).


minEvictableIdleTimeMillis 1000 * 60 * 30The minimum amount of time an object may sit idle in the pool before it is eligable for eviction by the idle object evictor (if any).


validationQuery:验证连接是否成功的SQL语句,至少返回一行,它会在所有应用的SQL语句执行之前运行一次,mysql推荐使用  SELECT 1    

testOnBorrow=true 表示从连接池中获取连接前是否进行验证(validationQuery)

testOnReturn=true 表示将连接归还连接池前是否进行验证(空闲时是否进行验证)

testWhileIdle=true 表示空闲时是否进行验证(空闲时是否进行验证) 需要配制timeBetweenEvictionRunsMillis、numTestsPerEvictionRun

timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程

numTestsPerEvictionRun:启动检查的线程数 

minEvictableIdleTimeMillis:链接最小的存活时间


配置情况:

validationQuery = select 1
timeBetweenEvictionRunsMillis = 3600000
minEvictableIdleTimeMillis = 18000000
testWhileIdle = true
testOnBorrow = true
testOnReturn = true

网上找到的别人的代码用例解释:http://agapple.iteye.com/blog/772507

dbcp的链接validate配置
dbcp是采用了commons-pool做为其连接池管理,testOnBorrow,testOnReturn, testWhileIdle是pool是提供的几种校验机制,通过外部钩子的方式回调dbcp的相关数据库链接(validationQuery)校验
dbcp相关外部钩子类:PoolableConnectionFactory,继承于common-pool PoolableObjectFactory
dbcp通过GenericObjectPool这一入口,进行连接池的borrow,return处理
testOnBorrow : 顾明思义,就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验
testOnReturn : 顾明思义,就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大
testWhileIdle : 关注的重点,GenericObjectPool中针对pool管理,起了一个Evict的TimerTask定时线程进行控制(可通过设置参数timeBetweenEvictionRunsMillis>0),定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。
timeBetweenEvictionRunsMillis,设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程
validateQuery, 代表检查的sql
validateQueryTimeout, 代表在执行检查时,通过statement设置,statement.setQueryTimeout(validationQueryTimeout)
numTestsPerEvictionRun,代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接.


Validate配置代码  
<property name="testWhileIdle"><value>true</value></property> <!-- 打开检查,用异步线程evict进行检查 -->  
    <property name="testOnBorrow"><value>false</value></property>  
    <property name="testOnReturn"><value>false</value></property>  
    <property name="validationQuery"><value>select sysdate from dual</value></property>  
    <property name="validationQueryTimeout"><value>1</value></property>  
    <property name="timeBetweenEvictionRunsMillis"><value>30000</value></property>  
    <property name="numTestsPerEvictionRun"><value>20</value></property>  
 相关配置需求:

目前网站的应用大部分的瓶颈还是在I/O这一块,大部分的I/O还是在数据库的这一层面上,每一个请求可能会调用10来次SQL查询,如果不走事务,一个请求会重复获取链接,如果每次获取链接都进行validateObject,性能开销不是很能接受,可以假定一次SQL操作消毫0.5~1ms(一般走了网络请求基本就这数)
网站异常数据库重启,网络异常断开的频率是非常低的,一般也就在数据库升级,演习维护时才会进行,而且一般也是选在晚上,访问量相对比较低的请求,而且一般会有人员值班关注,所以异步的validateObject是可以接受,但一个前提需要确保能保证在一个合理的时间段内,数据库能完成自动重联。

0 0
原创粉丝点击