zoukankan      html  css  js  c++  java
  • Docker 容器内分析 java程序占用 cpu 高问题排查分析

    作者: 张首富
    时间:2021-07-08
    wx: y18163201
    

    背景描述

    我们目前所有的 java 服务都是封装在 docker 里面的,今天做压力容量测试的时候发现有个服务占用cpu 300%,想找到是这个 java 程序的那个线程造成的问题,把问题反馈给开发让他们去修复。

    下面所使用的容器镜像都是通过:Docker容器内执行 jvm 分析工具命令 文章内的打包方式构建的;如果你发现你的 jvm 参数不能使用,那么建议你参考我的 dockerfile 进行构建

    分析过程

    通过监控发现 A 服务占用 cpu 过高;(prometheus+grafana+cadvisor构建的监控)

    image-20210708143717398

    等到宿主机上使用 top 判断是否真的是这个容器造成的 CPU 高

    top
    进入交互模式 按键盘 c 是按照 CPU 使用率进行排序
    

    确定是此服务没有跑了。那么开始分析是这个进程的那些线程出现的问题;因为我们服务都是封装在容器里,namespaces 和属主机上是隔离的,所以我们到容器里面去分析

    docker exec -it A sh
    apk add openjdk8  //安装 jvm 分析工具
    apk add htop      // 安装 htop 我们能更加清楚的看到是哪个线程占用 cpu 高,不需要借助其他命令;
    

    进到 docker 容器内执行命令htop 进去到 htop 页面按shift+p按照 CPU 使用率排序。

    image-20210708154354189

    找到 cpu 使用率前几的线程号。记录下来

    使用dk自带命令jstack获取此时的线程快照并输入到文件中: jstack -l > ./jstack_result.txt 命令(为Java进程的id号)来获取线程快照结果并输入到指定文件。

    jstack -l 7 > 1.txt 
    

    使用 printf "%x " 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

    /home/work # printf "%x
    " 162
    a2
    /home/work # printf "%x
    " 163
    a3
    /home/work # printf "%x
    " 169
    a9
    /home/work # printf "%x
    " 164
    a4
    

    转换后的结果分别为a2,a3,由于16进制以0x开头,所以对应的16进制的线程号为0xa2和0xa3。

    我们在刚才生成的线程快照中找 nid=0xa2,nid=0xa3 的线程

    image-20210708154738051

    然后把这些提供给开发让开发去查看代码。

    到此 docker 容器内分析 java cpu 使用率高的问题排查完成,

    补充

    在属主机上可以使用 top -Hp PID 来找线程使用 cpu 占用高的。

  • 相关阅读:
    alpha测试和beta测试的区别
    当设计师遭遇HTML5
    软件开发项目中如何进行风险管理
    程序员应知——关注细节
    与Janet关于敏捷测试若干问题的Q&A
    软件开发中的哲学——世界的本原是物质(一)
    软件开发中的哲学——写在前面
    软硬兼施让客户满意
    浅谈DBA的角色以及与业务的关系
    连接access时的REGDB_E_CLASSNOTREG(0x80040154)错误
  • 原文地址:https://www.cnblogs.com/shoufu/p/15000940.html
Copyright © 2011-2022 走看看