阅读本文大概需要 2.8 分钟。
MySQL 对我说 「Too young, too naive!"
大概过程
在测试环境 Docker 容器中,在跨进程调用服务的时候,A 应用通过 Dubbo 调用 B 应用的 RPC 介面,发现 B 应用介面超时错误,接著通过 debug 和日志,发现具体耗时的地方在于一句简单 SQL 执行,但是耗时超过 1000ms。
通过查看资料库的进程列表,发现是有死锁锁表了,很多进程状态 status 处于 sending data,最后为锁住的表添加索引,并且 kill 掉阻塞的请求,解除死锁,服务速度恢复正常。
下面记录的是大致排查过程:
通过观察业务代码,确认没有内存溢出或者其它事务问题,于是只能考虑 Docker 环境的资料库和 jvm 底层详情了。
使用 Druid 监控 SQL 执行状态
通过日志,发现有一句 SQL 严重超时,一句简单 SQL,原本是批量插入多条记录,为了定位问题,测试时 Mybatis 只插入一条记录,但即便如此,还是耗时 10 秒。