一次现网问题定位-慢接口告警
背景
本系统借助公司平台,持续对慢接口进行监控,当慢接口的比例超过一定阈值时就会告警。某日隔壁组收到慢接口告警,找我帮忙定位。定位前,我已先让运维临时扩容快速解决问题。
定位过程
先确认系统是否过载
首先观察各项指标,确认是否有资源过载,导致接口处理变慢。
- CPU:CPU利用率过高,会导致请求处理较慢。
监控发现cpu利用率最大也就50%,当前负载不是问题。 - tomcat http-nio线程利用率:http-nio线程池是处理请求的线程池,默认是200.如果线程池满载后,后续请求只能暂时先放到任务队列里面,等线程池当前任务处理完后在处理。所以如果http-nio线程池利用率100%后,也会阻塞请求的处理。
监控发现利用率不高,最大的20%左右,不过少量实例在告警期间指标有冲高,5%->20%. - 数据库连接池利用率:同上,数据库连接池如果满载,其他线程获取数据库连接时,只能等待其他的线程释放,这个也会导致请求阻塞,响应变慢。
监控发现连接池的利用率也不高。 - 内存利用率,如果内存使用率很高,gc频繁也会导致系统响应变慢。
通过监控可以看到内存使用率也很正常,老年代GC频率(监控只有老年代的GC数据)及时长也没太大异常。
初步定位,并未发现明显的问题点。不过少量容器http-nio利用率指标有冲高,应该是这几台实例上的请求变慢了,导致http-nio线程释放变慢。遂找运维确认,慢接口是不是都是这几台实例上的,得到答复,是。
确认实例间为啥有差异
从上面可以发现,少量实例与其他实例有差异。慢接口都是该部分实例产生的,从cpu使用率来看,该部分实例也明显比其他的高(有问题的实例cpu50%左右,没问题的20%左右)。
所有的实例规格都是一致的运行参数也是一致的(我们用的公司的docker,规格及参数都是按单个部署单元-微服务设置的,所有都一样)。现在相同的东西,跑出了不同的结果,肯定是某些地方有差异。接下来就寻找差异的过程。
系统一致,跑出来的结果不一样,首先有可能是负载不一样。因此先排查负载是否不均衡。
-
负载均衡是否有问题,导致更多的请求到了问题实例上,通过监控中的网络流量,以及通过访问日志算出各个实例的请求量,结果发现基本没啥差别,因此排除该问题。
-
虽然请求量是一样,但是每个请求的计算量不一样,会不会部分计算量大的正好路由到问题实例上。通过监控发现cpu高的,一直高,所以不太可能是这个问题。不可能恰好计算量大的一直路由到问题实例上,而且通过访问日志发现,出问题的时候,问题实例上,所有接口都变慢了,其他实例上几十毫秒就返回的(接口逻辑非常简单),在问题实例上,几百毫秒才返回。50%的cpu利用率其实并不是特别高,还不至于成为瓶颈点,导致接口慢10倍以上。从上面现象来看,像是GC停顿导致的,gc停顿会暂停所有线程,使所有请求都变慢,因此去检查GC日志。发现有问题的实例young gc特别频繁,更进一步发现问题实例的新生代大小为30MB左右,而没问题的300MB左右。
到此问题已经基本明确,相同的启动参数,相同的机器规格,跑出来的新生代大小不一样。30MB的太小,很容易就满了,需要执行young gc,业务高峰期时会让问题更明显。
明确问题后,我让运维配置-xmn=300MB,强制让新生代启动时大小一致,而不是靠jvm运行过程中的动态调整,保证各个实例的状态一致。调整后,cpu下降了10%以上,问题也不在出现,gc日志也都正常了。至此问题告一段落。
该问题的后续
运行一段时间后,虽然慢接口的问题没有在出现,但是后面运维在公司开发布会之前,对系统做巡检发现cpu最大有40%,找我确认是否有风险,需不需要库容。
通过监控发现,部分实例cpu老是比其他的高10%+
经过前面的定位经验,只能继续找差异点,根据前面的经验来看,不太可能是负债不均衡的问题,因此通过网络流量的监控确认后,便不再往这方便深挖。
下一步就是进登录容器使用top命令对比一下两边,是否有差异。
结果,cpu高的实例,gc线程的cpu使用率更高,并通过gc日志发现,相同的年轻代,cpu使用率高的实例,gc花费的时间更长。
cpu高的实例,young gc花费了20ms以上
cpu低的实例,young gc花费了10ms左右
之前已通过gc参数,保证各个实例的年轻代大小一样。young gc后,回收的内存差不多。每个实例跑的业务是一样的,分配的对象也是基本差不多的。从上可以得到一个结论,相同的gc计算量,不同实例,花费的时间不一样。从我的认知来看,只能是底层硬件有差别,于是找平台确认底层硬件。平台告诉我,进容器通过cpuinfo看到的硬件信息就是真实。
于是通过命令查到,cpu利用率高的cpu型号如下
cpu利用率低的,cpu型号如下
明显下面的cpu 频率更高,而且通过查阅资料6278c不仅制程比6161高,而且6278c比6161晚出4年,架构更先进。到此问题高一段落。