1. 问题现象
有一天下午运营反馈管理台谈论外放接口操作老是超时,处理不成功。
2. 问题定位剖析过程
2.1 收集信息
出现问题后首先检查PINPOINT监控,发现那天下午有很多管理台接口超时,超时接口大部分都是如下
update comment set xxx=?
然后在ELK上查找相关容器日志,发现有很多数据库报错日志,报错信息如下
RecoverableDataAccessException ### Error update database ...
从上面两个当地能够看出可能是数据库存在问题,检查数据库可能存在问题。
检查对应数据库监控,发现流量和IO根本正常,数据库连接数也正常。
接着检查是否是存在大的业务或许锁表
// 检索InnoDB存储引擎中当时活动业务的信息,并依照它们的开端时刻进行排序。
SELECT
trX_id,
trx_state,
trx_started,
trx_weight,
trx_mysql_thread_id,
trx_query,
trx_operation_state
FROM
information_schema.innodb_trX
ORDER BY
trX_started DESC;
// 发现两个活泼业务,一个trx_started是下午 16:19 没有对应的sql trx_mysql_thread_id为1
// 另外一个trx_started是 17:56 对应的sql update comment_a xxx trx_mysql_thread_id为2
//持续使用sql查询InnoDB存储引擎中的锁等候状况,以便了解哪些业务正在被堵塞以及它们正在等候的资源
SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, LEFT(r.trx_query, 30) AS waiting_query,
b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, LEFT(b.trx_query, 30) AS blocking_query
FROM information_schema.innodb_lock_waits AS W
INNER JOIN information_schema.innodb_trx AS b ON b.trx_id = W.blocking_trx_id
INNER JOIN information_schema.innodb_trx AS r ON r.trx_id = W.requesting_trx_id
ORDER BY blocking_thread DESC;
//发现其间为waiting_thread 为2 blocking_thread为1的记载,阐明2在等候1完成
// 检查innodb_lock_wait_timeout参数配置时刻,待确认
发现有超凡业务,业务从下午4点多已经开端,一向没有开释,运营保障时已经挨近6点。
2.2 紧迫躲避问题
有长业务未开释不太正常,联络运维将此业务KILL调,管理台操作正常
KILL 1
2.3 持续剖析问题
KILL调进程时刻段搜索ELK日志,发现有数据库连接相关的报错,依据连接仓库找到详细报错代码。 结合代码剖析大约原因如下:
主要原因有两个:
- thread1守时使命在获取需求外放的视频数据后,使用一个
非常大的业务
,并且在加@Transactional
没有指定timeout- 默认状况下,
@Transactional
注解的timeout
特点值为-1,表明不设置超时时刻,业务将无限期等候直到履行完成或发生其他原因导致的回滚。 - 每个视频外放操作比较复杂,需求调用风控判断视频是否能外放获取检测结果,成功后需求更新一系列缓存值,耗时较长
- 默认状况下,
- 存在对谈论更新操作死锁条件,存在业务表更新资源出现循环依赖状况
- 类似死锁可参阅这个实例:事例1:依据字段值查询(有索引),假如不存在,则插入;不然更新 只要将insert改为update
- 死锁条件可参阅这个文章:并发-基础概念
3.问题解决
此处主要讲述问题解决措施:
- 临时解决方案:kill 守时使命业务,防止再次出现大业务,与运营沟通暂停视频外放守时使命,改为人工履行
- 长期解决方案:
-
- 破坏死锁发生条件,更新谈论数据时,依照一致的次序更新表
-
- 将视频外扩大的业务拆小,每个视频外放一个业务,同时
@Transactional
增加超时时刻
- 将视频外扩大的业务拆小,每个视频外放一个业务,同时
-
- 单个
@Transactional
拆小,保留其间数据库更新操作,其他如查询视频审核放在业务之外
- 单个
-
4.举一反三
团队内加大对业务使用和死锁的认知,输出事例集和加入到编程标准中。