Kevin's blog Kevin's blog
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档

Kevin

你可以迷茫,但不可以虚度
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档
  • 常见问题

    • 常见面试题
    • Mybatis一级缓存问题
    • 一次 “NPE 没有堆栈” 的排查记录
    • 🛠CPU飙高保留现场
      • ✅ 方案 A:JFR 持续录制(强烈推荐,低开销)
      • ✅ 方案 B:CPU 超阈值时自动抓线程栈(轻量+文本)
      • ✅ 方案 C(可选):临时做一次 60 秒 CPU 火焰图
      • 用哪个?
  • 数据库

  • 代码技巧

  • 浏览器

  • spring应用

  • 使用Java Agent字节码技术扩展
  • 什么是AP,什么是CP,什么是CAP
  • RabbitMq相关
  • ELK查询技巧
  • 性能优化手段
  • 经验技巧
  • 常见问题
kevin
2026-02-28
目录

🛠CPU飙高保留现场

# ✅ 方案 A:JFR 持续录制(强烈推荐,低开销)

前提:容器里有 JDK(你能 jps,基本满足)。

1)启动一个 5 分钟环形缓冲的 JFR:

# 以 PID 1 的 Java 进程为例
jcmd 1 JFR.start \
  name=SpikeWatch \
  settings=profile \
  disk=true \
  maxage=5m maxsize=128m \
  dumponexit=true \
  filename=/tmp/omall-jfr.jfr
1
2
3
4
5
6
7
8
  • settings=profile:采样器(CPU/热点/锁等),开销很小
  • maxage=5m:只保留最近 5 分钟数据(环形缓冲)
  • 随时可保留最近窗口

2)当你发现刚刚有 spike 或想要留档时,立刻 dump:

jcmd 1 JFR.dump name=SpikeWatch filename=/tmp/omall-$(date +%s).jfr
1

把文件拷出:

kubectl cp <ns>/<pod>:/tmp/omall-1699999999.jfr ./   # 或 docker cp
1

用 JDK Mission Control 打开 .jfr 就能直接看到最热方法、热点线程、锁竞争、分配等。

小技巧:让它一直跑着就行,几乎不影响性能;出事就 dump 最近 5 分钟。

# ✅ 方案 B:CPU 超阈值时自动抓线程栈(轻量+文本)

有了 procps 后(你已经能 top -p),用下面脚本持续巡检,超过阈值就连抓多次栈:

cat >/usr/local/bin/cpu-spike-dump.sh <<'SH'
#!/bin/sh
PID=${1:-1}        # 目标 Java 进程
THRESH=${2:-200}   # 触发阈值(%),多核可>100
INTERVAL=2         # 轮询间隔(秒)
OUT=/tmp

echo "[cpu-spike-dump] watch pid=$PID thresh=$THRESH%"
while :; do
  CPU=$(ps -p $PID -o %cpu= | awk '{print int($1)}')
  [ -z "$CPU" ] && sleep $INTERVAL && continue
  if [ "$CPU" -ge "$THRESH" ]; then
    TS=$(date +%Y%m%d-%H%M%S)
    echo "[cpu-spike-dump] spike $CPU% at $TS, dumping stacks..."
    for i in 1 2 3 4 5; do
      jcmd $PID Thread.print > "$OUT/thread-$TS-$i.txt" 2>&1 || \
      jstack $PID            > "$OUT/thread-$TS-$i.txt" 2>&1
      sleep 1
    done
  fi
  sleep $INTERVAL
done
SH
chmod +x /usr/local/bin/cpu-spike-dump.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

运行:

/usr/local/bin/cpu-spike-dump.sh 1 200
1
  • 200 表示总核为 2 个时占满两个核才触发(按需改)
  • 触发时会在 /tmp 生成 thread-*.txt 多份,便于比对哪个线程一直热

如果你的 BusyBox ps 不支持 -o,就保持你已安装的 procps;否则可改为读取 /proc/1/stat 计算 CPU,但不如上面稳定。


# ✅ 方案 C(可选):临时做一次 60 秒 CPU 火焰图

若允许下载二进制,可用 async-profiler(极低开销采样):

# 假设已把 async-profiler 的 profiler.sh 放到 /opt/aprof/
bash /opt/aprof/profiler.sh -d 60 -e cpu -f /tmp/cpu.svg 1
1
2

把 cpu.svg 拷出直接浏览器打开,一眼看到最热栈。


# 用哪个?

  • 长期守护:选 方案 A(JFR),一直开着,事后 dump 最近 5 分钟。
  • 不想装工具,只要文本证据:选 方案 B,超阈即抓 5 份 Thread.print。
  • 要最清晰的热点图:方案 C(需要放入 async-profiler)。
上次更新: 2026/02/28, 09:08:42
一次 “NPE 没有堆栈” 的排查记录
Oracle技巧

← 一次 “NPE 没有堆栈” 的排查记录 Oracle技巧→

最近更新
01
AI是如何学习的
02-28
02
提示词工程实践指南
02-28
03
chatGpt提示原则
02-28
更多文章>
| Copyright © 2022-2026 Kevin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式