题目:应用启动后前几分钟,Load、RT、CPU 等飙高,如何定位,可能的原因是什么?
难度:low
标签:practice/performance, practice/capacity-planning, practice/debug
评分:⭐⭐⭐⭐☆(4/5)
首先看一下监控,确认这些标高的时间节点是什么情况?是启动后就开始逐渐的梯形的,就阶梯形的逐渐升高,还是怎么样?确认出现问题跟发布的根本关系,然后检查发布的内容是否有什么特殊的内容,是否会导致这个情况。
应用,如果是 Java 应用的话,看一下对应的 Java 的看板,包括 ZAL 加载类的情况、类加载器,然后内存的使用情况等一系列的具体的参数,相关的指标,GC,然后是否有大量的 GC,看一下 GC 的指标,是否有高并发进入在这个时间节点,然后类加载的参数的情况、类加载的数量的情况,是否有什么特殊的波动。
看一下请求接口方面,具体是所有接口都出现了问题,还是某些接口出现了问题。这个接口接口的监控,看一下是否是有个别接口并发量突增。如果是个别接口的话,检查一下这对应接口情况。
根据绩效指标、接口监控,磁盘的情况也要看一下磁盘跟机器的情况,有可能意外的日志导致磁盘方面满了,都是有可能的。然后观察一下磁盘的比例是否有相关的告警,磁盘是否拉满,这些都有可能产生 load、RT、CPU 标高。
检查到具体原因了,根据上面的指标看到了具体原因,然后开始进行相应的处理。如果是因为上线新功能导致的问题,那么对紧急对新功能进行回滚,然后把环境保留,把日志相关的下下来,然后看新功能具体是什么原因,然后回滚确保线上没有问题,正常可以使用。对新功能进行更改排查,具体原因是什么?
如果不是新功能导致的,而是突然的并发流量导致的。那么检查这个流量的持续情况,来源是否正常,是否是攻击,还是某些大促的活动导致的。
如果是攻击,对应攻击做相应的处理。比如 IP 过滤,然后就用户过滤、账号过滤、区域过滤等等,把非正常的请求拦截掉,防止服务继续出现问题。
如果是正常请求,大促活动,那么这个需要评估一下,为什么这个大促活动没有做?大促的活动产生的流量超出预期很多,对应需要做评估,然后做扩容也好,做一些临时的扩容,可能需要做临时扩容,临时加机器。如果是服务上存在问题,先回滚,业务存在问题先回滚,回滚,然后对应加缓存,提高并发也好,检查具体的哪出现了设计问题也好,然后流量问题也好,对应相应处理。
优点:
不足:
补充:
核心考点定位:考察"性能问题排查方法论"——从现象到根因的分层下钻,以及 Java 应用冷启动特有的耗时来源。
知识点拆解:
load = 运行态进程数 + D 状态进程数。CPU 打满看 C1/C2 编译和热点方法;D 状态多则看磁盘 IO / 网络阻塞考察方向:
vmstat 1(d 状态)、pidstat(单进程 CPU)、ss -s(连接状态)、Prometheus JMX 指标延伸递进面试题:
java -XX:+PrintCompilation 或 JFR 观察编译事件;生产上可主动调预热接口触发cat /proc/loadavg 对比 vmstat 1 的 r/b 列;可能是 GC STW(CPU 时间没算到用户态)【一句话结论】
面试官您好,"启动后几分钟飙高"是典型的冷启动问题,我先从时间轴确认是渐变还是突增,然后分三层排查:JVM 冷启动(JIT/连接池/缓存)、系统资源(CPU/D 状态/磁盘)、业务流量(灰度比例/依赖方)。
【三点展开】
第一,Java 冷启动三件事:JIT 没预热,热点方法还在解释执行;连接池刚建,TCP/TLS 握手开销大;本地缓存空,全部穿透到 DB/Redis。用 arthas dashboard 看类加载数是否还在涨,jcmd <pid> VM.event 看 C1/C2 编译事件,基本能锁定是不是 JIT 没追上。
第二,Load 飙高要区分是 CPU load 还是 D 状态。vmstat 1 看 d 列,d 大说明卡在 IO,可能是日志刷盘、NFS 卡住、或者 FullGC STW 把 CPU 时间挤到用户态之外。这时候看 arthas 的线程状态,WAITING/BLOCKED/DUMPED 多不多。
第三,处置有优先级:先降级/限流(秒级),再回滚(分钟级),最后扩容(小时级)。如果是新功能问题,回滚后要保留现场抓线程 dump 和 heap dump 分析根因,别急着清理环境。
【一句边界】
当然,如果是灰度只发了一台机器、且没有预热接口,用户流量直接被冷实例承接,这种场景下排查完还是要推预热机制,光靠排查没用。