当前位置: 首页 > news >正文

CPU狂飙900%如何分析?怎么定位?怎么溯源处理

当你的服务器CPU飙升到900%,系统卡顿、响应迟缓、业务受阻,这种令人焦虑的场景是否让你束手无策?别慌,这并不是世界末日,只要掌握正确的分析与定位方法,就能快速找到问题根源,并有效解决。

CPU 飙升到 900%,到底是哪些因素导致?如何快速定位问题并溯源处理?

分析 CPU 飙升的常见原因

CPU 使用率异常高的情况,通常可以归因于以下几类问题:

  • 代码问题: 死循环、大量的计算密集型任务或低效算法。
  • 流量暴增: 高并发请求导致系统资源耗尽。
  • 数据库瓶颈: SQL 查询未优化,导致数据库CPU占用高。
  • 外部依赖问题: 消息队列、第三方接口阻塞。
  • 恶意攻击: DDoS 攻击或者僵尸进程。

案例:
某电商平台在促销活动期间,用户访问量激增,导致多个服务的CPU飙升。排查发现,问题是由于缓存穿透,导致大量请求直接打到数据库,引发资源争夺。

01 场景1:MySQL进程飙升900%

评估:

大家在使用MySQL过程,想必都有遇到过CPU突然过高,或者达到200%以上的情况

数据库执行查询或数据修改操作时,系统需要消耗大量的CPU资源维护从存储系统、内存数据中的一致性。

并发量大并且大量SQL性能低的情况下,比如字段是没有建立索引,则会导致快速CPU飙升,如果还开启了慢日志记录,会导致性能更加恶化。生产上有MYSQL 飙升900% 的恶劣情况。

定位:
  • 使用top 命令观察,确定是mysqld导致还是其他原因。

  • 如果是mysqld导致的,show processlist,查看session情况,确定是不是有消耗资源的sql在运行。

  • 找出消耗高的 sql,看看执行计划是否准确, index 是否缺失,或者实在是数据量太大造成。

处理:
  • kill 掉这些线程(同时观察 cpu 使用率是否下降)

一般来说,肯定要 kill 掉这些线程(同时观察 cpu 使用率是否下降),等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些 SQL。

  • 进行相应的调整(比如说加索引、改 sql、改内存参数)

index 是否缺失,如果是则建立索引。也有可能是每个 sql 消耗资源并不多,但是突然之间,有大量的 session 连进来导致 cpu 飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,比如说限制连接数等;

优化的过程,往往不是一步完成的,而是一步一步,执行一项优化措辞,再观察,再优化。分析当前的数据量、索引情况、缓存使用情况。目测数据量不大,也就几百万条而已。接下来就去定位索引、缓存问题。

经过询问,发现很多查询都是走MySQL,没有用到缓存。

既然没有用到缓存,则是大量请求全部查询MySQL导致。通过下面的命令查看:

图片

发现类似很多相同的SQL语句,一直处于query状态中。

图片

初步分析可能是 user_code 字段没有索引导致。接着查询user表的索引情况:

图片

发现这个字段是没有建立索引。增加索引之后,该条SQL查询能够正常执行。


没隔一会,又发生大量的请求超时问题。接着进行分析,发现是开启了 慢日志查询。大量的SQL查询语句超过慢日志设置的阀值,于是将慢日志关闭之后,速度瞬间提升。CPU的使用率基本保持在300%左右。但还不是理想状态。

紧接着将部分实时查询数据的SQL语句,都通过缓存(redis)读写实现。观察一段时间后,基本维持在了70%~80%。

总结:

其实本次事故的解决很简单,就是添加索引与缓存结合使用。

  • 不推荐在这种CPU使用过高的情况下进行慢日志的开启。因为大量的请求,如果真是慢日志问题会发生日志磁盘写入,性能贼低。

  • 直接通过MySQL show processlist命令查看,基本能清晰的定位出部分查询问题严重的SQL语句,在针对该SQL语句进行分析。一般可能就是索引、锁、查询大量字段、大表等问题导致。

  • 再则一定要使用缓存系统,降低对MySQL的查询频次。

  • 对于内存调优,也是一种解决方案。

02 场景2:Java进程飙升900%

一般来说Java 进程不做大量 CPU 运算,正常情况下,CPU 应该在 100~200% 之间,但是,一旦高并发场景,要么走到了死循环,要么就是在做大量的 GC,  容易出现这种 CPU 飙升的情况,CPU飙升900%,是完全有可能的。

定位: 
CPU飙升问题定位的一般步骤是:
  • 首先通过top指令查看当前占用CPU较高的进程PID;

  • 查看当前进程消耗资源的线程PID:top -Hp PID

  • 通过print命令将线程PID转为16进制,根据该16进制值去打印的堆栈日志内查询,查看该线程所驻留的方法位置。

  • 通过jstack命令,查看栈信息,定位到线程对应的具体代码。

  • 分析代码解决问题。

处理:

1、如果是空循环,或者空自旋。

处理方式:可以使用Thread.sleep或者加锁,让线程适当的阻塞。

2、在循环的代码逻辑中,创建大量的新对象导致频繁GC。比如,从mysql查出了大量的数据,比如100W以上等等。

处理方式:可以减少对象的创建数量,或者,可以考虑使用 对象池。

3、其他的一些造成CPU飙升的场景,比如  selector空轮训导致CPU飙升 。

处理方式:

参考Netty源码,无效的事件查询到了一定的次数,进行 selector 重建。

采用top命令定位进程,登录服务器,执行top命令,查看CPU占用情况,找到进程的pid

图片

很容易发现,PID为29706的java进程的CPU飙升到700%多,且一直降不下来,很显然出现了问题。

使用top -Hp命令定位线程

使用top -Hp命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况(按shft+p按照cpu占用进行排序,按shift+m按照内存占用进行排序)

此处按照cpu排序:

图片

多个线程的CPU占用达到了90%多。我们挑选线程号为30309的线程继续分析。

使用jstack命令定位代码

  • 线程号转换5为16进制

printf “%x\n” 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

图片

转换后的结果分别为7665,由于导出的线程快照中线程的nid是16进制的,而16进制以0x开头,所以对应的16进制的线程号nid为0x7665

  • 采用jstack命令导出线程快照

通过使用dk自带命令jstack获取该java进程的线程快照并输入到文件中:

图片

命令(为Java进程的id号)来获取线程快照结果并输入到指定文件。

图片

  • 根据线程号定位具体代码

在jstack_result.txt 文件中根据线程好nid搜索对应的线程描述

图片

图片

根据搜索结果,判断应该是ImageConverter.run()方法中的代码出现问题,当然这里也可以直接采用

图片

来定位具体代码

图片

分析代码解决问题
重启项目后,测试发现项目运行稳定,对应项目进程的CPU消耗占比不到10%

图片

随着云计算和微服务的普及,系统复杂度日益增加,CPU飙升的情况并不少见。许多企业缺乏完善的性能监控和溯源机制,导致问题处理效率低下。强化监控体系、提升性能优化能力已成为技术团队的刚需。

CPU 飙升不是无解的难题,而是系统给出的一个信号,告诉你某些地方需要改进。通过监控、定位、溯源、优化,你不仅能解决当前的问题,还能为系统未来的稳定性打下基础。

“CPU飙升时,别慌,它是问题的表象,解决它,你才是真正的幕后英雄。”

 

http://www.lryc.cn/news/524410.html

相关文章:

  • Excel 技巧17 - 如何计算倒计时,并添加该倒计时的数据条(★)
  • Java中的阻塞队列--以LinkedBlockingQueue为例
  • 16.5万煤气柜柜位计故障分析
  • 高效沟通驱动LabVIEW项目成功
  • 大模型之三十三- 开源Melo 语音合成
  • 论文复现:四轮转向车辆后轮转角控制方法研究
  • 【UFEN】基于多层特征融合和多任务学习的多模态情感分析
  • uniapp的插件开发发布指南
  • 【Linux系统】—— 编译器 gcc/g++ 的使用
  • [微服务]注册中心优化
  • C++ ——— 模拟实现 vector 类
  • 大华相机DH-IPC-HFW3237M支持的ONVIF协议
  • 【Java】常用工具类方法:树形结构、获取IP、对象拷贝、File相关、雪花算法等
  • 豆瓣电影Top250的数据采集与可视化分析(scrapy+mysql+matplotlib)
  • 2024微短剧行业生态洞察报告汇总PDF洞察(附原数据表)
  • PHP语言的数据库交互
  • flutter跨端UI框架简介
  • 自动化标注平台开源,基于 yolov8标注平台可本地部署
  • Walrus Learn to Earn计划正式启动!探索去中心化存储的无限可能
  • 第35天:安全开发-JavaEE应用原生反序列化重写方法链条分析触发类类加载
  • 【mptcp】ubuntu18.04和MT7981搭建mptcp测试环境操作说明
  • 【数据分析(二)】初探 Pandas
  • 第9章:Python TDD解决货币对象相等性比较难题
  • 更新布局元素的属性
  • UDP協議與代理IP介紹
  • QT 中 UDP 的使用
  • leetcode刷题记录(七十二)——146. LRU 缓存
  • 深圳大学-计算机系统(3)-实验一MIPS指令集实验
  • Java面试专题——面向对象
  • 知行合一:解决有心无力的问题,解决知易行难的问题,知行合一并不意味着事事都要合一,而是....