Apache DBCP连接池获取数据库连接慢的优化处理

版权声明:因时间精力和个人能力,文章内容难免不足,简陋。请谅解.... https://blog.csdn.net/jdk2006/article/details/51570283

客户反馈新上线的某个系统在登录时会等待一会,非常影响用户体验。通过沟通了解到其他已部署上线的系统没有出现这个问题,感觉解决这个问题应该是一个比较棘手。

系统是很早开发的一个项目,在其他客户都部署几次,但是没有去读过这个系统的源代码。通过分析源代码,了解到系统通过封装JDBC,并利用Apache DBCP作为连接池实现DAO层执行系统SQL,并且在系统启动初始化的过程没有初始化连接池,只有当用户第一次登陆系统时,数据库连接池才被初始化。

搭建开发,跟踪调试程序,发现系统在间隔一段时间后,系统从数据库连接池获取Connection非常耗时,大概10s,还不如不使用数据库连接池。

最后定位到程序所在Apache DBCP连接池获取数据库Connection耗时长。原因是数据库DBA对系统连接资源,进行了限制,空闲连接数据库会进行释放,而系统中默认配置的DBCP连接池,是不对池中的连接做测试的,有时连接已断开了,但DBCP连接池不知道,还以为连接是好的呢。应用从池中取出这样的连接访问数据库一定会报错。

解决方案:
1、定时对连接做测试,测试失败就关闭连接。
2、控制连接的空闲时间达到N分钟,就关闭连接,然后连接池可再新建连接。

下面就是DBCP连接池,同时根据解决方案的配置DBCP

validationQuery = "SELECT 1"  验证连接是否可用,使用的SQL语句
testWhileIdle = "true"      指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testOnBorrow = "false"   借出连接时不要测试,否则很影响性能
timeBetweenEvictionRunsMillis = "120000"  每2分钟运行一次空闲连接回收器
minEvictableIdleTimeMillis = "600000"  池中的连接空闲10分钟后被回收,默认值是30分钟。
numTestsPerEvictionRun="3" 每次空闲连接回收器线程(如果有)运行时检查的连接数量,默认值是3.

Oracle数据库可以通过下面SQL语句查看某个用户连接信息:

SELECT s.username,s.status,s.machine,osuser,spid,
TO_CHAR (logon_time, 'dd/mm/yyyy hh24:mi:ss') logon_time,
last_call_et idle_time,
TO_CHAR (TRUNC (last_call_et / 3600, 0))||' '||' HRS '||TO_CHAR (TRUNC ((last_call_et - TRUNC(last_call_et / 3600, 0) * 3600) / 60, 0)) ||' MINS' idle_time_hour_minute,
module
FROM v$session s, v$process p
WHERE TYPE = 'USER'
and s.USERNAME='用户名'
AND p.addr = s.paddr
ORDER BY last_call_et desc;

作者 @zokaper
2016 年 01 月 17日

猜你喜欢

转载自blog.csdn.net/jdk2006/article/details/51570283