故障原因
下午15:23左右出现大量慢sql导致mysql服务器的cpu飙升到100%
处理过程
阿里云查看性能趋势,发现在15:22:20cpu飙升到100%
排查思路:
一般引起cpu飙升的原因很可能是扫描行数骤增
查看15:22:20之前的扫描行数,并未发现明显异常
查看15:22:20之前1小时内的慢sql,并按平均扫描行数排序,发现慢sql集中在报表查询部分,除报表查询外有一句根据授权范围查询往来单位的sql的平均扫描行数排在所有慢sql的第一位
该sql从sql本身层面优化空间不是很大,可能需要做一些拆分后分布执行或者通过代码来实现的尝试
通过sql洞察查询发现查询报表的两句sql选了支付时间范围为今年,
ent_code为xxxx,执行时间花了6分多钟,导致cpu飙升,
由于sql过长,在sql洞察中显示不全,先计算sql开始时间加上执行时间得到执行完成时间,
通过慢sql的慢日志明细找到该sql,尝试在只读实例上执行该sql,发现执行时间在2s以内,
说明该sql是由于cpu飙升引起执行出现异常,并不是导致cpu飙升的原因
当前处理方案为联系B做了一次数据库主备切换,大概在15:29分左右恢复正常
报表层面查询计划对原数据库实例增加一个只读实例,把report-service的数据库连接指向只读实例,减少cpu飙升带来大面积不可用的情况
在代码层面做了一些调整,把除初始化以外查询相关的用到countDownLatch查询的部分都改成单线程查询了,这样可以一定程度上减少同时占用的数据库连接数
暴露的问题
最近几次出现的故障每次的现象和原因都不一样,从每次出现故障的情况来看引起故障的主要原因有以下几点
1.慢sql查询
2.openapi接口频繁请求,部分查询未加索引,引起大量全表扫描
改进措施
目前已经做了以下几点改进措施
1.报表服务切换到只读实例上运行,这样修改后确保报表查询引起的异常,不会影响主流程
2.优化访问量较多的慢sql,通过增加索引方式来做优化
3.除初始化方法外的查询方法中用到多线程查询的地方改成单线程
后续可以考虑的改进措施
1.openapi接口限流,目前接口访问在nginx层面有每秒5次调用的限制,后期可能需要对接口做分类,并对每种类别分别设置限流规则