前几天项目中遇到,每次服务重启后,页面点击总是响应缓慢,反应肯定是数据库的原因,但是单独打开mysql发现查询并不慢,看项目错误日志,报异常是,数据库连接池被耗尽,导致sql无法执行,但是查看对应的报错sql代码,找不到问题所在。后来,多次查看代码,多次分析,并且修改了数据库连接池大小,但是还是被耗尽连接池,发现肯定不是配置的原因。然后通过一下语句具体定位
1:查看当前的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
这个发现 有地方在更新心跳结果时候一直阻塞,发现此时 40个连接池一直处于阻塞,
2:查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
发现此时事务一直处于等待提交状态,
3:查看当前等锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
查出来如果需要的话可以使用kill 线程id (trx_mysql_thread_id 列)
例如:
kill 328907576756328;
然后查看心跳代码,发现用tcp去发送心跳给对方的中控,然后更新我们的sql表中心跳字段,但是由于这些代码是写在service中,我们的事务也是在service中,所以我们用tcp发送心跳包给对方,由于设备有30多台,此处用了循环去发送tcp,导致事务提交阻塞,把连接池耗尽,然后把这个过程提取到controller层,发现问题顺利解决