前言
春天到了大地都复苏了,寂静了很久的 cpu 也开始缓缓复苏了,所谓前人埋坑前人填坑,随同着阿里云监控报警,线上 CPU 使用率暴增,于是就开始了排查之路。
呈现问题景象
因为服务的 cpu 暴增达到肯定水平,导致服务假死,接口调用全副返回 502 不可用,链接超时导致服务器方面无奈给予失常的反馈。
通过查看阿里云数据库 RDS,慢 sql 日志进行剖析,发现数据库的 CPU 使用率在某一时间达到了 96%,这不完犊子了。
导出监控平台剖析的慢 sql,看到这个 sql 均匀的执行工夫,真的是再次刷新了我的认知,均匀执行法工夫 2 分多钟,这怕是执行的黄花菜都要凉了。
问题排查
首先依据阿里云剖析的慢 sql 进行再次剖析,sql 必定是有问题的,而导致服务不可用的起因还须要看微服务的负载配置,于是我去查看了该服务 Nacos 的配置。这里咱们看到该服务 Ribbon 超时工夫为 15 妙,就意味着接口如果执行超过这个工夫接口就无奈继续执行,从而呈现服务假死不可用的景象。
服务接口调用长时间没有反馈,ribbon 负载平衡会触发熔断机制,对服务进行爱护,让服务不可调用。
波及接口
通过慢 sql 对应到问题接口,对接口逻辑进行梳理,排查接口波及到的 sql。
通过对业务逻辑剖析,发现这个接口对慢 sql 执行了两次,一次是失常分页查问数据,第二次是没有加分页参数,那么将全表查问,对查问的后果依据字段进行过滤,过滤出 count 条数。
其次是发现前端对这个接口进行两次调用,咱也不晓得为什么,然而在申请上看来,拜访该页面同一接口的确进行两次调用,原本接口就很慢了,这几乎就是一个暴击。
慢 sql 剖析
因为动静 sql 比拟长,我只筛选我认为 sql 不是很适合的中央
查问列中用 select 嵌套查问
- sql 中呈现大量字段 in 的查问
In 是走索引的查问,然而当 in 括号外面的条件比拟多的状况下,就是传入的参数这个 list 列表长度比拟大的状况下,是不走索引的,会进行全表扫描,in 最终走不走索引其实是跟前面的数据有关系的。
表中数据量
主表大略在 25w 多数据,关联表比拟大在 170w 数据。
主表索引加了很多,未必就是一件坏事,索引的设置齐全依照搜寻条件来设置也未必对,波及到关联表肯定要增加索引。
关联表呈现了很多反复数据,因为不理解之前业务的逻辑,不太分明为什么呈现很多反复数据,这也是表中数据量很大的起因,从而导致影响查问效率。
接口优化
既然当初问题找到了,就能够进行优化了,我说下我优化的思路,次要是从下往上进行优化。
慢 sql 优化,次要是针对嵌套查问改为 left join 左外联查问,缩小了 in 查问,查问进去的数据在代码中进行筛选,缩小了一些不必要的索引。
通过 conut()统计须要的条数,在所有 count 外面,count()是效率最高的了,有趣味的敌人能够去理解下。
- 业务代码方面,限度了工夫筛选的区间,从原来的不限工夫勾选范畴,跟业务进行沟通后,调整为只容许抉择一周的工夫范畴进行查问,前后端都进行限度。
优化后果比照
由此可见优化后的执行效率还是比拟高的,线上服务也没有在报警了,然而还有其余服务在报警…. 还有磁盘使用率达到 90%…. Wtf 真的是优化之道路漫漫啊。
总结
此次对于接口的优化点还不是很深,次要点是对代码、sql、业务进行优化,还未波及到分表、退出缓存热点数据进行预热、批改负载平衡超时工夫等…
其实偶然的填坑也是一种学习的形式,不说了持续填坑了,哦!不对优化代码了~