java 程序cpu占用过高排查

布满荆棘的人生 2024-03-23 20:52 147阅读 0赞

1、top命令查看cpu占用最高程序

  1. top

f795df5e6a6a40f8b8132d2c5ca263bd.png

取得cpu占用最高的PID: 27791

2、判断java程序是直接运行在宿主机还是在容器中

方式一 cgroup

  1. cat /proc/<PID>/cgroup

如果输出中包含有类似 /docker/<container_id> 的字符串,就表示该进程在 Docker 容器中。

" class="reference-link">6392f724d1b041f2b34effc4d5ee90a2.png

方式二 lsns

lsns命令查看程序的命名空间 ,如果显示的命名空间信息中有 ipc, mnt, net, pid, user, uts,那么该 PID 很可能在一个 Docker 容器中。

  1. lsns -p PID

fc4283ffd43d452587823d848a0c3285.png

方式三 jps

jps命令查看当前在服务器执行的java程序

  1. jps

ee9f254f8db542b38460bbbe3d4165a5.png

a、占用CPU最高的PID在jps的列表里,java进程可能运行在服务器,可直接执行jstack PID

b、占用CPU最高的PID不在jps列表里,java进程可能运行在容器中。

3、执行jstack

a、java进程直接运行在宿主机上

jstack命令查看线程、堆栈情况

  1. jstack PID

b、java进程运行在docker容器里

(1)宿主机上直接jstack

  1. #1、查看java进程在容器内的PID
  2. docker exec -it $containerid /bin/ps x
  3. #2、获取容器内JAVA_HOME路径
  4. docker inspect --format '{
  5. { range .Config.Env }}{
  6. { if eq (index (split . "=") 0) "JAVA_HOME" }}{
  7. { index (split . "=") 1 }}{
  8. { end }}{
  9. { end }}' $containerid
  10. #说明:docker inspect --format '{
  11. {.Config.Env}}' $containerid 是获取容器内的环境变量,如果没配环境变量需要到容器里查看,可用 which java 命令
  12. #3、执行jstack
  13. docker exec -it $containerid $JAVA_HOME/bin/jstack $pid

(2)进入到容器执行jstack

定位docker容器。根据lsns -p PID获取到的信息(jar包名称可定位项目)定位到docker容器,需人工判断

  1. lsns -p PID
  2. docker ps | grep 容器相关信息(名称、端口、容器ID等)

进入到docker容器

  1. docker exec -it 容器ID /bin/bash
  2. #如果/bin/bash不存在,可使用/bin/sh

容器内查看进程ID,ps、jps、top命令都可以

执行jstack PID

4、分析jstack信息

发表评论

表情:
评论列表 (有 0 条评论,147人围观)

还没有评论,来说两句吧...

相关阅读

    相关 redis cpu占用排查

    redis是用"单线程-多路复用io模型"来实现高性能的内存数据服务的,这种机制避免了使用锁,但是同时这种机制在进行sunion之类的比较耗时的命令时会使redis的并发下降。