之前说到,我们的慢sql因为早期的程序员都很初级,因此,线上跑的慢sql满天飞;虽然做了DB隔离,把慢sql的影响局限在各自的微服务内,但还是要去解决。
当时的环境是,我们的业务迭代的速度非常疯狂,我们没有余暇去优化sql,甚至团队有能力优化的也没有几个,面对这个问题,我想到一个比较有趣的办法,做慢sql排名。
排名之前,是要做监控,我们通过druid收集sql的监控信息,把他们放到表里做排序,排序的规则是,按照出现次数 * RT时间来排;然后,我们只解决每天排名的TOP10,一年的时间,我们就几乎没有慢sql再出现了。
解决了慢sql的历史问题,那新出现的问题,我们怎么快速解决呢?我相信大多数的公司都会有慢接口报警、慢sql报警的,只是这些报警一般不大会有人看。在我以前的公司,一般都是运维童鞋定期会拉出一个长长的列表,在全公司层面发出来,让大伙去解决。
我们是怎么做的呢?答案是,日志接入钉钉。
通过钉钉的及时通信和提醒效果,第一时间触达给后端人员,再通过测试和后端共同的维护机制,保障每个慢sql都能被很及时的解决。
说到慢sql,有一个场景我要提一下,比如,突然某一个时段,我们发现接口出现了很高的RT延时,我们该如何排查呢?这里顺便给出一下我的排查思路。
- 先看慢接口,通过慢接口来确定是后端的哪个应用。
- 再去查找后端的应用,查看是否用运行异常,一般来说就看看ECS上的mem、cpu、网卡是否有飙升,如果这些都正常,再检查是不是FULL GC来引起的。
-
我的思路是,优先看那个时段有没有出现FULL GC,因为FULL GC的stw的时间很长,最长能超过1秒,一个健康的应用,一天内也不会出现一次full gc;young gc,一般来说按频率和时长来看,我的经验值是单次young gc最好不要超过100ms,1分钟尽量不要超过5次young gc。我们的jdk的版本是8,截图中你看到了元空间,因此它是G1。这里有些童鞋在问,JDK11已经有ZGC了,为什么不用11呢?答案是成本,我们不确定目前的中间件中有多少和jdk11是不兼容的,我们的ARMS(鹰眼-全链路监控)就不兼容,因此,盲目切换11带来的收益,远没有损失大。
-
这里出道题,如果linux上发现系统资源都被一个java进程占用了,通过什么步骤能查到呢?(要把大象放冰箱,总共分几步呢?)
- top
- top -H
- printf "%x\n" 16进制异常线程号
- jstack 进程号|grep 16进制异常线程号 -A90
-
-
如果整体应用没有问题,服务器各项指标没有波动,那继续排查数据库,现在的阿里云的mysql(RDS)的监控已经做的非常好了,支持各种维度的性能监控、全量sql查看、慢sql查看&分析等。我的思路是,先查找有问题的那个时间段,再将那个时间段的全量sql进行统计排序,一般用耗时比例来看看是哪个sql占用了最多的资源(不一定占用资源最多的就是有问题的),再通过扫描行数,来看看是不是出现了不合理的sql。