持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
问题背景
前几天遇到了一个非常有趣的“事故”案例,搜索调用下游rpc服务接口,监控报警超时,于是搜索系统的负责人“气势汹汹”的找到下游接口服务方问,你们接口是不是挂了,调用老是超时导致接口监控可用率低。下游服务端也是一脸懵,没有收到任何监控报警呀?于是打开监控,发现服务接口性能监控没有任何问题,双方监控不一致,于是开始了问题的排查和定位。
我先讲一下搜索构建索引的业务场景,方便我们去更好的理解出现的问题点。
搜索每天都会提前构建门店商品的索引,流程如下:
1、查询平台所有商家
2、开启多线程查询每一个商家下的所有门店列表、每个商家下的所有商品
3、组装门店商品信息,开启多线程
4、查询库存接口,过滤可售商品
5、开启多线程补全门店商品价格和促销
问题表象
在查询库存接口报错-错误如下:Waiting provider return response timeout ....
乍一看,肯定是库存接口超时导致的线程中断,而且通过异常堆栈可以看到,超时时间 2278ms,已经超过了设置的等待最大返回时间800ms,这就导致了搜索构建商品的时候库存数量缺失,中断索引构建。
问题排查
排查这种客户端、服务端接口性能监控不一致的总体思路前提,要了解一下各个环节点的耗时情况。
对于客户端来说,耗时主要由:建连时间 + 序列化时间 + 等待服务端处理时间组成;
对于服务端来说,耗时主要由:线程池等待时间 +服务处理时间 +结果序列化时间组成。
所以,对于我们一线开发,如果要对RPC耗时进行调优,最需要关注的,有客户端的路由寻址、序列化方式,有服务端的服务线程池等待、反序列化、服务端处理速率、结果序列化 这几块。
回到我们排查问题的思路上来,我们首先看下服务端的问题。
服务端:
1、当然,看到这个日志报错的异常堆栈后,第一时间肯定也会联想到,是不是库存接口挂了,有问题呢?于是联系到了库存的同学看下provider端的ump监控,结果发现,监控性能全都正常,而且通过性能监控可以排除都没有问题-如下图
(1)服务端线程池等待(通过接口性能可以直观看出来,如果有线程等待性能肯定变慢)-没问题
(2)结果序列化时间-没问题
(3)服务器处理时间-没问题
2、确认库存接口没问题后,接下来怀疑是不是库存返回的数据过大,等待服务端处理时间太长导致的线程中断,通过哪些指标可以确认呢?
(1)接口入参限制-最大300个
(2)库存缓存key-value非常小 几kb左右
(3)服务端服务器出流量 来看下是否有大流量返回-通过监控看也都正常,如下图
客户端
1、排除了服务端没有问题后,我们来看下客户端服务器,我们来看下客户端服务器业务线程耗时的环节
(1)建连时间
(2)序列化时间
(3)等待服务端处理时间
通过日志报错可以确定,目前出问题的是等待服务器处理时间线程超时,那么为什么超时呢?可能会存在如下几个原因
(1)cpu负载过高
(2)线程数太多,导致业务线程池打满走拒绝策略
(3)fullgc
先来看
(1)cpu负载情况,通过监控发现,cpu负载在可控范围内,并非100%负载,整体压力可控。
(2)业务线程池情况,通过监控可以看到线程数量很稳定,并没有出现飙升的现象
(3)最后怀疑是不是有fullgc,结果发现,构建某一个商家的时候,频繁的触发fullgc,构建其他商家没有问题,看了gc监控情况后,也印证了这个怀疑~!
每一次fullgc的平均耗时是20167ms,我们都了解fullgc会导致STW(Stop The World),在fullgc期间会挂起业务线程,gc后才会重新唤醒业务线程,最终导致了我们的jsf线程等待相应超时报错,给我们一个下游rpc接口有问题的错觉。
那么,问题来了,为什么会频繁fullgc呢?肯定是存在了大对象,导致每次gc的时候gc不掉。导致频繁的触发fullgc的阈值。
探寻导致频繁fullgc的大对象来源
一开始List<可售库存> 只保存可售的门店商品。
后来加了个判断,如果商家上架数量超过2w,那过滤条件就改成了List<可售库存+库存数量大于0>
出问题的商家恰好满足这些条件,而且这个商家下上架的sku 21W,散列到800个门店维度,轻松上亿。导致出现了大对象,然后频繁的触发fullgc
问题解决
1、调整合理的jvm参数,避免频繁fullgc(治标不治本,最好的方式还是优化业务代码)
2、修改业务代码,优化过滤逻辑,避免大对象产生gc不掉
总结
1、如果出现客户端、服务端监控不对等的情况出现 一定要有一个清晰的排查思路,要知道哪些环节点会导致监控不对等的情况
2、针对流程进行逐项排查,发现问题点
3、这种就属于比较麻烦的问题,因为通过横向扩容是无法解决问题的,我们在开发过程中,一定要进行充分的压测,尽量提前避免这种问题产生