cpu负载是什么原因 如何解决(cpu负载是怎么回事)cpu负载是什么原因 如何解决(cpu负载是怎么回事)

关注健康
关注真实体验

cpu负载是什么原因 如何解决(cpu负载是怎么回事)

cpu负载是什么原因 如何解决(cpu负载是怎么回事)

排查步骤

1 先查看有无错误日志(回滚)、上下游调用是否正常(通知、降级、熔断)

2 若是单台飙升则重启机器或置换

3 若全部都飙升则说明程序里有线程一直长时间占用CPU则先摘流一台保留现场用来后续分析问题,其它重启快速恢复服务

4 top查看机器进程占用CPU最高进程号 (此时可以通过jinfo pid 了解服务信息), top -Hp pid找到CPU占比最大的线程

5 将线程号转换为十六进制 $printf "%x\n" 4858 12fa (线程栈里是十六进制)

6 jstack pid | grep -A 10 [线程16进制] 明确CPU负载如此高的线程到底在干什么 比如是GC线程(GC异常频繁)

7 找寻为何GC如此频繁原因:jstat -gc、gcutil、class 查看堆空间、大对象情况

8 jmap -dump 生成快照文件分析(zip压缩、摘除流量再执行)

9 发现JceSecurity对象占据了90%的堆空间

10 通过可视化工具继续查看此对象各属性,发现其中有个Map属性 Map<Provider, Object> verificationResults 量级巨多

11 verificationResults的v类型是BouncyCastleProvider 从代码里找这个类的应用处

12 发现是在一个方法里每次调用都会生成一个对象塞入Map,将这个对象变成static,每次调用不要创建对象而是复用这个类对象

以上是很常见的CPU飙高的场景,表面是CPU不足,其实是因为FullGC长期运行大量占用CPU的结果


历史经验1 YongGC线程导致

业务代码导致的内存泄露or溢出修复

创建大量对象但一直被引用(数据库获取大量数据追加到List、方法调用每次都new对象放入对象级别Map属性)

创建大对象(超大String对象,逻辑内不断改写 直接放入老年代)

资源用完未主动回收(Socket、Stream)

每次运行加解密都会new一个BouncyCastleProvider对象,放倒Cipher.getInstance()方法中

每次运行到加解密都会向这个map put一个对象,而这个map属于类的维度,所以不会被GC回收。这就导致了大量的new的对象不被回收

2 业务线程导致

业务代码有死锁或死循环导致CPU长期占用(除非时间片到了否则不会主动让出CPU)


另外如果程序中有序列化反序列化、正则表达式匹配逻辑,也有因数据处理耗时过大导致CPU飙高的风险

未经允许不得转载: 九月健康网» cpu负载是什么原因 如何解决(cpu负载是怎么回事)
分享到: 更多 ( 0)