网站大图做多大尺寸,泸州市建设规划局网站,郴州网页设计招聘,设置字体颜色的网站CPU 使用率在系统监控中是一个非常重要的指标。对于大多数 Web 应用来说#xff0c;它们往往是 IO 密集型的#xff0c;因此只会在某些时刻可能会出现 CPU 突然飙升的情况#xff0c;随后很快就恢复正常。然而#xff0c;当收到报警并想要排查问题时#xff0c;CPU 飙升的…CPU 使用率在系统监控中是一个非常重要的指标。对于大多数 Web 应用来说它们往往是 IO 密集型的因此只会在某些时刻可能会出现 CPU 突然飙升的情况随后很快就恢复正常。然而当收到报警并想要排查问题时CPU 飙升的情况可能已经过去无法直接查看当时 Java 进程内的线程堆栈信息。
为了解决这个问题本文实现了一个小工具它在 CPU 飙升时自动保存堆栈信息方便后续问题的追踪。
该工具实现了两个主要功能
当 CPU 使用率达到预设的阈值时自动保存当前 Java 进程的线程堆栈信息输出占用 CPU 使用率最高的线程 ID。
本文选择在 Linux 系统上实现这个工具因为大多数应用都是部署在 Linux 环境中本来想实现一个 MacOS 版本的脚本但捣鼓了半天由于格式以及函数存在差异所以就没继续纠结了
脚本如下
#!/bin/bash
if [ $# -ne 1 ]; thenecho Usage: $0 j_pidexit 1
fij_pid$1
threshold90while true; docpu_info$(ps -p $j_pid -o %cpu)cpu_usage$(sed s/%//g $cpu_info)current_time$(date %Y-%m-%d %H:%M:%S)echo [-----$current_time] Current CPU Usage: $cpu_usage%if [ $(echo $cpu_usage $threshold | bc -q) -eq 1 ]; thenthread_id$(top -b -n 1 -H -p $j_pid | grep -E ^\s*[0-9] | sort -k9 -r | head -n 1 | awk {print $1})echo [-----$current_time] Detected! PID: $j_pid ; Thread ID: $thread_idjstack_output$(jstack -l $j_pid)jstack_filenamejstack_$(date %Y%m%d%H%M%S).txtecho $jstack_output $jstack_filenameecho [$current_time] jstack_filename: $jstack_filenamefisleep 10
done
可以看看效果这是模拟的消耗 CPU 的 Java 代码
/*** author dongguabai* date 2023-07-21 13:11*/
public class Test {public static void doSth() {while (true) {double x Math.random() * Math.random();}}public static void main(String[] args) {new Thread(new Runnable() {Overridepublic void run() {doSth();}}, highcpu_thread).start();}
}执行 Java 代码
[rootMiWiFi-R4CM-srv javaTest]# javac Test.java
[rootMiWiFi-R4CM-srv javaTest]# java Test执行脚本
[rootMiWiFi-R4CM-srv javaTest]# sh monitor.sh 9581
[-----2023-07-21 01:37:12] Current CPU Usage: 99.3%
[-----2023-07-21 01:37:12] Detected! PID: 9581 ; Thread ID: 9590
[2023-07-21 01:37:12] jstack_filename: jstack_20230721013713.txt查看线程 ID
查看线程堆栈
Attach Listener #9 daemon prio9 os_prio0 tid0xb768fc00 nid0x25a0 waiting on condition [0x00000000]java.lang.Thread.State: RUNNABLEDestroyJavaVM #8 prio5 os_prio0 tid0xb7607400 nid0x256e waiting on condition [0x00000000]java.lang.Thread.State: RUNNABLEhighcpu_thread #7 prio5 os_prio0 tid0xb768ec00 nid0x2576 runnable [0xa4bb8000]java.lang.Thread.State: RUNNABLEat Test.doSth(Test.java:13)at Test$1.run(Test.java:20)at java.lang.Thread.run(Thread.java:748)可以看到效果还是可以的。
注意事项
在生产环境中使用此工具时需要注意以下几点
jstack 命令可能对系统性能产生一定影响需要谨慎使用并避免频繁执行 如果 Java 进程非常大有很多线程那么收集线程堆栈信息的操作可能会耗费较多的系统资源触发脚本时 Java 进程本身已经处于高负载状态运行jstack命令可能会导致 Java 进程的响应时间增加最好设置一个触发阈值频繁地运行 jstack 命令收集线程堆栈信息可能会在一定程度上增加系统负担 脚本最好保存在一个不容易被意外杀掉的地方以确保在 CPU 飙升时能正常执行。在应用刚启动的时候可能由于初始化等操作导致短暂的 CPU 飙升因此脚本可设置延迟执行避免误报。