西部数码主机 | 阿里云主机| 虚拟主机 | 服务器 | 返回乐道官网
当前位置: 主页 > 开发教程 > linux教程 >

DRUID|ORACLE防火墙对连接的影响

时间:2016-04-28 23:42来源:未知 作者:好模板 点击:
虚拟账户产品投产之后,观察到这么一个现象:在无人访问应用一段时间之后(应该是两小时左右),再次访问应用时,后台db日志显示一直在opening jdbc connection...,程序卡死,过16分钟之

虚拟账户产品投产之后,观察到这么一个现象:在无人访问应用一段时间之后(应该是两小时左右),再次访问应用时,后台db日志显示一直在opening jdbc connection...,程序卡死,过16分钟之后,程序正常执行,后台db日志显示已经获取到了新的数据库有效连接;

排查过程:起初都不知道16分钟花在何处,哪个函数的调用上;最后还是仔细的根据异常的堆栈信息,看最后执行语句所在位置,再一级级回溯回去,定位到druid源码的位置,加了蛮多的debug日志在里面,才最终定位到JdbcUtils.close(realConnection)执行了16分钟,是jdbc在关闭一个被防火墙drop掉的连接的时候出现了问题,异常信息是IO Exception: broken pipe,是说应用跟oracle服务器之间的连接通道断了。

解决:在stackoverflow上搜索了相关问题,比较确定这个问题确实是由防火墙引起的(一方面oracle服务器不会主动去断开跟应用的连接;另一方面druid我们设置的参数testOnBorrow=true,只会在获取连接的时候进行连接有效性检测,且druid并没有定时探测机制,所以利用排除法确定这个问题是防火墙引起),所以现在有两种解决方案:

在oracle服务器侧加入DCD(Dead Connection Detection)检测,保持连接有效性(但生产环境下不敢随便改基础配置信息);

在druid这一侧加入一个定时检测机制(durid本身没有,需要自己实现一个独立的线程,难点在于我们没办法保证该线程能够与现有druid逻辑完全融合且该线程一直不挂);

在druid基础之上修修补补,应该是可以的,所以我们的解决方案:在获取数据库连接时,先计算当前连接的空闲时间(已设置testWhileIdle=true),当空闲连接超过一小时即调用抛弃连接的函数,且让线程池(开了一个10个大小的线程池)里面的一个线程去做这件事情,主线程继续遍历,直到找到(或者新建)一个有效的连接为止。

(责任编辑:好模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容