目录

  • 一、场景
  • 二、排查
  • 三、原因
  • 四、解决



记录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代码块