记一次线上cpu飙升100%的排查过程

记录了一次线上服务响应慢的问题排查过程,最终定位为数据库脏数据触发的死循环BUG。

大家好,我是烤鸭:

   最近没怎么写技术文章,还是得回归下初心,正好前几天出现个线上问题,记录下排查过程。

问题描述

某个时间点,接收到接口响应慢报警。

过一会收到服务器cpu可用率低(<10%)报警。

去cat上查看发现younggc次数频繁。

在这里插入图片描述

排查思路

  • 业务代码近期没改动和发版,出现问题大概率是中间件或者环境问题(服务器硬件或网络)。

  • 尝试回滚代码和扩容机器。

  • 输出堆栈日志和gc快照,调整jvm参数。

排查结果

  • 中间件和网络:

    使用到的中间件包括 es、redis、mysql,分别去监控和连接查看,没问题。

    网络也在机器上测试,没问题。

  • 回滚和扩容

    尝试回滚到上一个稳定版本和增加扩容机器。

    还是有问题。

  • 输出堆栈日志和gc快照,调整jvm参数。

    其实堆栈日志是可以解决问题的,不过当天晚上排查的时候,没有过度关注业务方法,导致错过了问题根源。

    gc快照分析结果,发现是tomcat的一个初始化对象占有较多(跟问题无关)。

在这里插入图片描述

在这里插入图片描述

总结

cpu升高和gc频繁,其实是两个问题,都可能会引起服务不可用。

单纯的cpu升高,基本确认是死循环问题,抓到对应的堆栈信息即可。

#抓取进程中cpu消耗高的线程
top -Hp pid
#线程id转成十六进制
printf '%x\n' tid
#抓取java线程堆栈
jstak-l pid

而gc频需要查看gc日志,是否引起oom。

实时查看gc情况,每隔5s打印一下gc情况。

jstat -gcutil pid 5000

输出gc快照。

jmap -dump:format=b,file=/data/dump.hprof pid

然后使用eclipse mat 或者 jprofiler 进行分析。

血泪教训

当天忽略了堆栈日志,过多的关注在gc上。

排查问题的思维定式,排查思路和实际执行不严谨,以致于错过问题根源。

运行了几年的代码都没出问题,不代表代码本身没问题,以堆栈日志和gc日志为准。

根本原因就是数据库脏数据触发了代码中一个死循环bug(运行了一年才发现,也是醉了)

<think>嗯,用户的问题是关于线上环境CPU占用率突然飙升时,一分钟内应该优先采取哪些紧急措施。从用户提供的引用来看,用户可能是一名运维工程师或者开发人员,正在面临线上故障,急需快速止损的方案。用户引用了三个资料,其中[1]强调了CPU爆满的严重后果,[2]提供了排查方法,[3]则展示了一个实际案例——日志配置错误导致的问题。这说明用户需要的是具体可操作的应急指南,而不是理论探讨。 用户可能正处于紧张状态,因为CPU100%会导致业务中断,所以回答必须直接、精准、步骤化。需要把最关键的三步(定位进程、分析线程、检查日志)拆解成可立即执行的命令序列。同时要提醒安全注意事项,比如避免直接kill关键进程。 注意到用户特别强调“一分钟内”,说明对时效性要求极。因此第一步的top命令必须放在最前面,因为这是最快速的定位手段。而保存现场快照的建议虽然重要,但可以放在第三步,因为当务之急是先控制住CPU使用率。 用户引用的案例[3]提到日志配置错误导致的问题,这个很典型,所以要在检查日志环节特别强调。但也要避免过度聚焦,因为其他原因(如死循环、恶意攻击)同样常见。 技术层面,需要确保命令的准确性:比如top -c的排序参数,jstack的线程号转换方法。同时给出替代方案,比如没有jstack时如何用其他工具。数学公式部分要处理线程状态统计的算法,但用LaTeX简单表达即可,避免复杂推导干扰主流程。 最后生成的三个相关问题都围绕深度排查,符合用户技术背景。特别是第二个问题(容器环境差异)很有针对性,因为现在很多系统都容器化了,排查方式确实不同。</think>当线上环境CPU占用率突然飙升100%时,**一分钟内的黄金操作流程**如下(按优先级排序): --- ### ⚡ 第一步:立即定位问题进程(10秒内) 1. **执行命令** ```bash top -c -o %CPU ``` 2. **关键观察点**: - 最顶部 **CPU占用最的进程PID**(如PID 2634)[^2] - `Load Average`值(若1分钟值远于5/15分钟值,说明突发负载) - 进程的**命令行参数**(如`java -Xmx4g`) > 📌 示例输出片段: > ``` > PID USER %CPU %MEM COMMAND > 2634 app 98% 15% java -Xmx4g ... > ``` --- ### 🔍 第二步:分析进程内部线程(20秒内) 1. **获取线CPU详情** ```bash top -H -p <PID> # 如 top -H -p 2634 ``` 2. **定位异常线程**: - 录**CPU线程ID**(如TID 2680) - 将线程ID转为十六进制(用于后续分析) ```bash printf "%x\n" 2680 # 输出 a78 ``` --- ### 🛠 第三步:保存现场快照(30秒内) 1. **抓取线程堆栈**(Java应用示例) ```bash jstack -l <PID> > jstack_$(date +%s).log ``` 2. **保留性能快照**(可选但关键): ```bash # CPU使用分布 perf record -p <PID> -g -- sleep 10 # 内存快照(若怀疑GC问题) jmap -dump:live,format=b,file=heap.bin <PID> ``` --- ### 🚨 第四步:紧急止血(根据场景决策) | **场景** | **操作** | |-------------------------|--------------------------------------------------------------------------| | **确认业务影响严重** | 重启服务实例(先保留现场快照!) | | **线程死循环/阻塞** | 用`kill -3 <PID>`触发线程dump后重启 | | **疑似恶意攻击** | 用`iptables`封禁可疑IP(结合`netstat -tnp | grep <PID>`) | | **日志暴增(引用[3])** | 立即停用错误日志配置,清理`/tmp`等日志目录 | --- ### 📌 关键注意事项 1. **禁止直接kill -9**:可能导致事务中断或数据损坏 2. **快速检查关联指标**: ```bash vmstat 1 5 # 检查上下文切换(cs)和阻塞进程(b) iostat -dx 1 # 排除磁盘IO瓶颈 dmesg -T | tail # 查看内核报错 ``` 3. **保留证据链**: `top`截图 + `jstack`输出 + 应用日志时间戳(后续根因分析核心依据) > 💡 **经验提示**:突发性CPU满载的**三大频诱因** > 1. 线程阻塞(如日志扫描线程陷入死循环[^3]) > 2. GC风暴(`jstat -gcutil <PID> 1000`观察GC时间) > 3. 代码死循环(数学计算未退出条件,如递归调用错误) --- ### 完整排查流程图 ```mermaid graph TD A[CPU 100%] --> B{top -c 定位进程} B --> C[录PID和命令行] C --> D{top -H 分析线程} D --> E[CPU线程TID] E --> F[保存jstack/perf快照] F --> G{是否可立即恢复?} G -->|是| H[重启实例] G -->|否| I[根据堆栈分析] I --> J[日志/配置检查] J --> K[修复后验证] ``` 通过以上步骤,1分钟内即可完成**关键现场保留**和**紧急止损**,为后续根因分析奠定基础[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烤鸭的世界我们不懂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值