目录
- 一、场景
- 二、排查
- 三、原因
- 四、解决
记录JDBC链接回收资源失败导致程序阻塞,使得前端页面一直在加载(转圈)、前端页面空白(只能展示静态HTML内容,没有对页面进行渲染)、前端http接口请求后status为pending的排查过程及解决方案
本文提到的问题并不一定是JDBC链接阻塞导致,也有可能是Jedis链接阻塞或其他有阻塞情况发生的代码导致
一、场景
1、前端页面一直在加载(转圈)
2、前端页面空白(只能展示静态HTML内容,没有对页面进行渲染)
3、前端http接口请求后status为pending
4、打开前端页面后,应发起的http请求没有发起 (这个情况比较奇特,具体原因未查明,但也是后端程序阻塞引起)
注:以上情况是在程序运行一段时间后才会出现,一旦重启程序则恢复正常,过一段时间后又会再次出现
二、排查
场景1、场景2、场景3都是有发起http请求,通过Debug对接口进行调试
1、通过Debug发现程序在获取JDBC链接时程序阻塞
1.1、JDBC链接队列
//JDBC链接队列
ArrayBlockingQueue<JDBCConnection> m_QueuePool;
1.2、执行以下代码时程序阻塞
//获取JDBC链接
JDBCConnection cnn = m_QueuePool.take();
2、程序已在finally代码块对JDBC资源进行回收,不应该存在链接数不足的情况
if(xxx){
try {
xxx;
} finally{
//回收JDBC链接
m_QueuePool.put(JDBC链接对象);
}
}
3、释放资源的代码编写有问题,finally写在if中,如果if条件不成立,则资源不会释放。在JDBC链接队列还存有链接数时,程序可以正常运行,在链接数不足时,程序阻塞
三、原因
1、回收JDBC链接的代码写在finally代码块中
2、finally代码块被写在if代码块中
3、由于if条件不成立,导致finally代码块中回收JDBC链接对象的代码没有执行
4、当JDBC链接对象被全部取出后,程序再次获取JDBC链接对象,导致程序阻塞
四、解决
1、使回收JDBC链接对象的代码不受if条件限制
2、使回收JDBC链接对象的代码一定会执行:finally代码块