目录

从宏观到微观:CPU排查的“破案”流程

第一阶段:应急响应——找到“谁”在捣乱

1. 全局视角:top命令的初窥

2. 进程内窥视:揪出问题线程

第二阶段:深入分析——理解“为什么”

3. 线程堆栈分析:查看线程在做什么

4. 性能剖析:perf与火焰图

第三阶段:解决方案——从临时止血到根因治理

案例1:算法优化——O(n²)到O(n log n)

案例2:锁竞争优化——减小锁粒度

案例3:JVM调优——GC优化

第四阶段:预防体系——建立监控与告警

总结:CPU优化思维模型


你的服务器不是突然发烧的,只是你一直没注意到它在咳嗽。

当我们收到第一道CPU使用率告警时,往往像是深夜接到急诊电话——系统正在高速路上飞奔,而CPU利用率仪表盘已经飙入红色区域。这种场景下,是手忙脚乱地重启服务,还是能够沉着冷静地找出真凶?

从宏观到微观:CPU排查的“破案”流程

排查高CPU问题就像侦探破案,需要从宏观现象逐步深入到微观代码,遵循严谨的推理路径。下图展示了一条高效的排查思路:

第一阶段:应急响应——找到“谁”在捣乱

1. 全局视角:top命令的初窥

当系统响应缓慢时,top命令是我们的第一响应工具:

top - 14:30:01 up 45 days,  8:32,  1 user,  load average: 3.02, 2.85, 2.10
Tasks: 231 total,   1 running, 230 sleeping,   0 stopped,   0 zombie
%Cpu(s): 85.3 us, 14.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15985.4 total,   152.4 free,   8345.8 used,   7487.2 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  10345.6 avail MemPID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
1123 appuser   20   0   12.3g   2.1g  23456 S  95.3  13.2   312:45.92 java
1458 mysql     20   0   15.6g   1.2g  12345 S  25.4   7.8   145:23.18 mysqld

这里我们立即可以发现几个关键信息:

  • 负载平均值:3.02(1分钟),2.85(5分钟),2.10(15分钟)——如果你的CPU是4核心,那么负载>4表示系统过载
  • CPU使用分布:用户空间(us)占85.3%,系统空间(sy)占14.7%——说明主要是应用程序自身消耗CPU,而非系统调用
  • 罪魁祸首:一个Java进程以95.3%的CPU使用率位居榜首

2. 进程内窥视:揪出问题线程

找到问题进程后,我们需要深入其内部,查看是哪些线程在消耗CPU:

# 查看Java进程中的线程CPU使用情况
top -H -p 1123# 或者使用ps命令
ps -L -p 1123 o tid,pcpu,comm | sort -k2 -nr | head -10

输出可能显示:

TID   %CPU COMMAND2234   45.3 java2235   35.2 java2236   12.1 java

现在我们已经将范围从进程缩小到具体线程。但线程ID是十进制,而Java堆栈中的线程ID是十六进制,需要转换:

printf "%x\n" 2234  # 输出: 8ba

第二阶段:深入分析——理解“为什么”

3. 线程堆栈分析:查看线程在做什么

获取线程堆栈是理解CPU使用率的关键步骤。对于Java应用,我们使用jstack

jstack -l 1123 > jstack.log

然后在jstack.log中搜索十六进制线程ID(0x8ba):

"HTTP-Processor-0" #23 daemon prio=5 os_prio=0 tid=0x00007f8a1c0d8000 nid=0x8ba runnable [0x00007f8a143f5000]java.lang.Thread.State: RUNNABLEat com.example.app.Encoder.encode(Encoder.java:45)at com.example.app.Service.process(Service.java:78)- locked <0x0000000712345678> (a java.util.HashMap)at com.example.app.Controller.handleRequest(Controller.java:123)

这是一个典型的发现:线程正在执行Encoder.encode方法,并且处于RUNNABLE状态,说明它正在消耗CPU。

4. 性能剖析:perf与火焰图

对于更深入的分析,perf工具可以生成火焰图,直观展示CPU时间消耗在哪里:

# 记录性能数据
perf record -F 99 -p 1123 -g -- sleep 30# 生成火焰图
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > flamegraph.svg

火焰图就像一个倒置的山脉,山峰的宽度表示该方法消耗的CPU时间比例。通过火焰图,我们可以快速识别出最耗时的代码路径。

示例:火焰图中宽阔的山峰表示CPU热点

第三阶段:解决方案——从临时止血到根因治理

根据分析结果,我们可以采取不同的解决策略:

案例1:算法优化——O(n²)到O(n log n)

假设我们发现热点在一个排序算法中:

// 优化前 - 冒泡排序 O(n²)
public void sortUsers(List<User> users) {for (int i = 0; i < users.size(); i++) {for (int j = i + 1; j < users.size(); j++) {if (users.get(i).getId() > users.get(j).getId()) {swap(users, i, j);}}}
}// 优化后 - 快速排序 O(n log n)
public void sortUsers(List<User> users) {Collections.sort(users, Comparator.comparingInt(User::getId));
}

效果:对于10,000个用户,优化前可能需要数秒,优化后仅需几毫秒。

案例2:锁竞争优化——减小锁粒度

如果发现大量线程阻塞在锁上:

// 优化前 - 粗粒度锁
private final Object lock = new Object();public void processUserData(User user) {
synchronized(lock) {  // 所有线程串行执行process1(user);process2(user);process3(user);
}
}// 优化后 - 减小锁粒度或使用并发集合
private final ConcurrentHashMap<String, Lock> userLocks = new ConcurrentHashMap<>();public void processUserData(User user) {
Lock userLock = userLocks.computeIfAbsent(user.getId(), id -> new ReentrantLock());
userLock.lock();
try {process1(user);process2(user);process3(user);
} finally {userLock.unlock();
}
}

效果:从完全串行处理变为按用户ID并行处理,吞吐量大幅提升。

案例3:JVM调优——GC优化

如果发现GC线程消耗大量CPU:

# 添加GC日志参数
java -Xmx2g -Xms2g -XX:+UseG1GC -XX:+PrintGCDetails -Xloggc:gc.log -jar app.jar# 分析GC日志,如果发现频繁Full GC,可以调整参数
java -Xmx4g -Xms4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar

第四阶段:预防体系——建立监控与告警

灭火重要,但防火更重要。建立完善的监控体系:

  1. 应用层监控:QPS、响应时间、错误率
  2. JVM监控:堆内存使用、GC频率与时间、线程状态
  3. 系统层监控:CPU使用率、负载、IO等待
  4. 业务层监控:关键业务指标,如订单创建速率

使用Prometheus + Grafana搭建监控面板,设置合理的告警阈值:

# CPU告警规则示例
groups:
- name: CPUAlertrules:- alert: HighCPUUsageexpr: process_cpu_usage{job="app"} > 0.8for: 5mlabels:severity: warningannotations:summary: "高CPU使用率 (实例 {{ $labels.instance }})"description: "CPU使用率超过80%,当前值: {{ $value }}"

总结:CPU优化思维模型

处理CPU问题不只是技术活,更是一种思维方式:

  1. 测量,不要猜测:没有数据支撑的优化是盲目的
  2. 全局视野,局部深入:先从整体找到方向,再深入细节找根因
  3. 权衡的艺术:CPU vs 内存、延迟 vs 吞吐量、开发成本 vs 性能收益
  4. 持续迭代:性能优化是持续过程,不是一劳永逸的任务

记住,CPU是我们最宝贵且最难扩展的资源之一。善待CPU,它会回报你以更稳定的系统和更低的云账单。

最好的CPU优化不是让代码跑得更快,而是让它做更少的事。——匿名性能工程师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921106.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921106.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921106.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何快速实现实时云渲染云推流平台的网络环境配置与端口映射

LarkXR是由Paraverse平行云自主研发的实时云渲染推流平台&#xff0c;以其卓越的性能和丰富完备的功能插件&#xff0c;引领3D/XR云化行业风向标。LarkXR适用于3D/XR开发者、设计师、终端用户等创新用户&#xff0c;可以在零硬件负担下&#xff0c;轻松实现超高清低时延的3D交互…

13、Docker构建镜像之Dockerfile

13、Docker构建镜像之Dockerfile 1、Dockerfile是什么 Dockerfile是Docker镜像的构建文件&#xff0c;它包含了一系列指令和参数&#xff0c;用于定义如何构建一个Docker镜像。通过Dockerfile&#xff0c;我们可以将应用程序和其依赖的组件打包到一个独立的镜像中&#xff0c;方…

TensorFlow 深度学习 | 三种创建模型的 API

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 TensorFlow 深度学习 | 三种创建模型的 API 在 TensorFlow 中,模型的构建方式非常灵…

LeetCode82删除排序链表中的重复元素 II

文章目录删除排序链表中的重复元素 II题目描述示例核心思想最优雅解法算法步骤详解示例1演示&#xff1a;[1,2,3,3,4,4,5]关键理解点1. 虚拟头节点的作用2. 重复检测逻辑3. 完全删除重复节点边界情况处理情况1&#xff1a;空链表情况2&#xff1a;单节点情况3&#xff1a;全部重…

蓝桥杯算法之基础知识(6)

目录 Ⅰ.os操作 Ⅱ.时间库&#xff08;很重要&#xff09; Ⅲ.基本单位换算&#xff08;ms&#xff0c;min&#xff0c;h的单位换算&#xff09; Ⅳ.时间戳 Ⅴ.文件读取 Ⅵ.堆 Ⅶ.math操作 Ⅷ.range&#xff08;&#xff09;方法单独使用 Ⅸ.python 的异常输出 Ⅹ.for…

多架构/系统图,搞懂:期货账户体系,太通透了!

Hi,围炉喝茶聊产品的新老朋友好!上周和大家聊了国内6大期货交易所清算交收,感兴趣的话烦请戳蓝色链接去学习,就当为下面学习作知识铺垫,更重要是温故知新,并保持知识连贯性。另外围炉特意整理了与账户相关的文章,如下所示: “保证金被扣”拆解期货交易所:清算交收体系…

python-对图片中的头像进行抠图

要实现对图片中人脸或头像进行抠图&#xff0c;可以使用 Python 的 人脸检测 和 掩码生成裁剪工具。这里提供几种实现方法&#xff0c;用于检测图片中的人脸区域并实现裁剪效果&#xff1a; 方案 1: 使用 OpenCV 和 Haar级联检测人脸并裁剪 步骤 1: 安装依赖 安装 OpenCV 和其他…

OpenLayers常用控件 -- 章节一:地图缩放控件详解教程

前言在Web地图开发中&#xff0c;缩放控件是用户与地图交互最基本也是最重要的功能之一。OpenLayers作为功能强大的开源地图库&#xff0c;提供了多种缩放控件来满足不同的交互需求。本文将结合一个完整的Vue.js示例&#xff0c;详细介绍OpenLayers中三种主要的缩放控件&#x…

拓扑学:数学领域的魅力之钥

拓扑学:数学领域的魅力之钥 关键词:拓扑学、连续变形、同胚、流形、代数拓扑、点集拓扑、应用数学 摘要:本文深入探讨拓扑学这一现代数学的重要分支,从其基本概念到高级理论,从纯数学研究到实际应用。我们将从点集拓扑的基础开始,逐步深入到代数拓扑和微分拓扑的复杂世界…

iOS 上架 uni-app 流程全解析,从打包到发布的完整实践

uni-app 作为跨平台开发框架&#xff0c;凭借“一套代码&#xff0c;多端运行”的特性&#xff0c;已经成为不少团队和个人开发者的首选。 然而&#xff0c;很多开发者在 iOS 应用上架环节&#xff0c;常常遇到流程复杂、工具分散、审核繁琐等问题。 本文将以 iOS 上架 uni-app…

go 语言map是线程不安全的如何处理

在 Go 语言中&#xff0c;map确实是线程不安全的。当多个 goroutine 并发读写同一个 map 时&#xff0c;会导致 ​race condition​&#xff08;竞态条件&#xff09;&#xff0c;可能引发程序崩溃或数据不一致。以下是解决方案&#xff1a;一、基本方案&#xff1a;使用互斥锁…

落地页测试case(Android视角)

落地页按钮或者adjust的链接的跳转功能和测试case&#xff08;Android视角&#xff09; 如果没有安装应用&#xff0c;跳转到应用商店的应用下载界面如果已经安装应用&#xff0c;跳转到应用内&#xff0c;再从应用内跳转到相应的页面如果落地页是在window打开&#xff0c;点击…

前端自动化打包服务器无法安装高版本 Node.js v22 问题解决

问题&#xff1a;安装高版本 node&#xff0c;报错。具体表现 当执行 node -v 命令时&#xff0c;系统提示多个 GLIBC_xxx 版本未找到&#xff0c;比如 GLIBCXX_3.4.21、GLIBC_2.27 等&#xff0c;这些是 node 程序运行所依赖的 Glibc 库的特定版本符号&#xff0c;当前系统安装…

shell脚本第七阶段--三剑客之awk

学习目标熟悉awk的命令行模式基本语法结构熟悉awk的相关内部变量熟悉awk常用的打印函数print能够在awk中匹配正则表达式打印相关的行一、awk介绍awk是一种编程语言&#xff0c;主要用于在linux/unix下对文本和数据进行处理&#xff0c;是linux/unix下的一个工具。数据可以来自标…

Unity 的游戏循环机制

Unity 的游戏循环机制在 Unity 中&#xff0c;游戏的运行是基于帧的。每一帧都遵循固定的执行顺序&#xff1a;处理输入执行游戏逻辑 (包括 Update、FixedUpdate 和协程)渲染场景显示帧为什么 GameTime.time 在同一帧内不变GameTime.time 是只读属性&#xff1a;它返回的是当前…

算法题(198):数字三角形

审题&#xff1a; 本题需要我们找到数字三角形中的最大路径总值&#xff0c;并输出 思路&#xff1a; 方法一&#xff1a;动态规划 由于本题的路径权值是路径上每一个值累加起来&#xff0c;问题具有阶段重复性&#xff0c;所以我们尝试使用动态规划解决此问题 &#xff08;1&a…

变频器实习DAY42 VF与IF电机启动方式

目录变频器实习DAY42一、工作内容1.1 OF229程序重新烧录和测试二、学习内容2.1 VF与IF电机启动方式1. VF&#xff08;Voltage Frequency&#xff09;启动电机2. IF&#xff08;Current Frequency&#xff09;启动电机总结附学习参考网址欢迎大家有问题评论交流 (* ^ ω ^)变频器…

B样条曲线,已知曲线上的某个点到起点的距离,确定这个点的参数u的值的方法

B样条曲线&#xff1a;已知弧长 L 求参数 u 的方法1. B样条曲线定义B样条曲线由以下要素定义&#xff1a;控制点&#xff1a;P₀, P₁, P₂, ..., Pₙ节点向量&#xff08; Knot Vector &#xff09;&#xff1a;U [u₀, u₁, ..., uₘ]曲线次数&#xff1a;k&#xff08;例如…

云计算学习100天-第44天-部署邮件服务器

目录 电子邮件通信——邮件服务器 基本功能 邮件通信的寻址 案例 网络架构 配置server服务器 电子邮件通信——邮件服务器 基本功能 为用户提供电子邮箱存储空间 处理用户发出的邮件——传递给收件服务器 处理用户收到的邮件——投递到邮箱 邮件通信的寻址 根据收件…

计算机视觉(七):膨胀操作

在计算机视觉中&#xff0c;膨胀是一种基本的形态学操作&#xff0c;主要用于处理和分析图像的形状。它通过“膨胀”或“放大”图像中的前景对象来增加其尺寸或连接断开的区域。 膨胀操作的工作原理类似于卷积&#xff0c;但使用的是结构元素 (structuring element)&#xff0c…