Docker容器cpu占用高问题排查方案之一

针对Java应用,我结合我们的docker环境写了一个容器cpu飙升问题精确排查步骤(注:有的镜像过于精简,一些命令工具是缺失的,所以要想实施以下方案,容器中的linux常用命令安装是需要解决的)

容器必备命令

top  -Hp   jvm进程ID      找到cpu占用最高的 jvm 线程ID

jstack    jvm进程ID         导出java线程栈信息

printf  “%x\n”  线程ID     将10进制数字转换成16进制数

下面是我在dev环境的测试情况

1、top命令查出Java进程ID,如下图为 54

Docker容器cpu占用高问题排查方案之一_第1张图片

2、查出java进程内 哪个线程ID占用cpu最高

top  -Hp  54

如下图最高的是线程ID为78的线程

Docker容器cpu占用高问题排查方案之一_第2张图片

3、将线程ID转换成16进制

printf  "%x\n"   78

Docker容器cpu占用高问题排查方案之一_第3张图片

4、抓取对应线程堆栈信息

jstack 进程号 | grep nid=0x+16进制线程号 -A 100

jstack  54   | grep  nid=0x51  -A  100

如下图就找到了最高的线程堆栈信息,进一步可以找到程序里的类和方法信息

Docker容器cpu占用高问题排查方案之一_第4张图片

5、下面自动化脚本

echo '----------begin----------'
count=1


if [[ x$1!=x ]]; then
  #statements
    count=$1;
fi


jvm_pid=$(top -n 1 | grep java | awk '{print $2}' )
echo  'jvm pid = '$jvm_pid


for i in $(seq 1 $count); do
  #statements
  max_cpu_tid=$( top -Hp $jvm_pid  -n 1  | awk 'NR==8' | awk '{print $2}' )
  echo 'cpu max java thread tid = '$max_cpu_tid
  tid16=$(printf "%x\n"  $max_cpu_tid)
  echo  'tid16 = '$tid16
  jstack  $jvm_pid | grep  nid=0x$tid16  -A  100
  echo '---------------------------------------------------------'
  sleep 1s
done


echo '----------end----------'

你可能感兴趣的:(公众号:,老吕架构,容器化部署,堆栈,docker,linux,java,jvm)