线上服务导致cpu飙升问题排查

3 篇文章 0 订阅

一、故障说明

        昨晚突然收到线上服务器cpu报警,登录监控平台看了下发现cpu瞬间飙升到60%。第一反应就是使用top命令去查看,发现是一个java进程。于是立刻使用jps -l命令定位到该java进程,发现是一个后台服务,按理说晚上没什么人去使用后台服务,而且它也没有定时任务,查看了服务的日志都没有发现异常情况。

二、故障排查

        既然是java进程导致的cpu飙升,于是我使用jstat -gcutil [pid] 5000命令去查看GC情况,结果发现Eden区的垃圾回收非常频繁,然后使用jmap -heap [pid]查看了当前java进程内存配置,Eden区分配了600M的内存,什么样的操作导致600M的内存都不够使用呢?于是我把Eden升级到了800M,结果还是一样CPU并没有降下来。看来一味增加内存是无法解决问题了,只能乖乖的去定位故障了。

三、故障定位

        我先是dump出当时的堆栈信息,然后使用MAT去分析,结果并没有发现什么有价值的信息。于是我就想还是要去查看堆栈内的实时数据来定位问题。
        这里使用的工具是Jprofiler,功能强大,界面友好,版本是9.2(大家可以去使用更新的版本,我这里使用9.2是因为网上找不到高版本的破解码,当前找不到破解码也可以试用)。我们都知道图表最能直观反映问题,而我们的线上服务器是linux,所以必须把指标抓取到本地的window服务器上这样才能用图表的形式直观展示。因此这里需要Jprofiler服务端(安装到linux)和Jprofiler客户端(安装在window),下面是对Jprofiler的安装、使用过程。

  1. Jprofiler下载
    Jprofiler9.2下载链接
    在这里插入图片描述

  2. Jprofiler在window下安装
    window版本我们直接在本地安装即可

  3. Jprofiler在linux下的安装
    linux版上传到远程服务器/opt目录下,然后tar -zxvf 解压(上传目录不一定是/opt,大家可以自行更改)

  4. 收集服务端信息
    然后在想要监控的服务启动脚本中增加下面这段代码(代码中的路径需要结合自身情况做修改,端口随便指定一个即可)

    -agentpath:/opt/jprofiler9/bin/linux-x64/libjprofilerti.so=port=23498,nowait
    
    // 修改完启动脚本后启动服务,然后查看下上面的端口是否启动
    netstat -lnp|grep 23498
    // 我们的监控信息需要通过23498端口传到客户端,因此需要在防火墙中开启该端口
    firewall-cmd --zone=public --add-port=23498/tcp --permanent
    // 重启防火墙
    systemctl restart firewalld
    // 查看端口是否生效
    firewall-cmd --list-ports
    

    (如果大家使用的阿里云等第三方云服务,还需要自行修改安全组配置)

  5. 客户端展示
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 问题定位
    首先我们第一眼看到的就是下面的图片,图片中有Memory、GC、Classes、CPU这几个指标。其中我们重点关注Memory、GC、CPU。可以看到Memory几秒钟就下降一次,那么是什么东西能顾在几秒钟内占据几百兆的内存呢?
    在这里插入图片描述
    我们知道Eden区属于新生代,新生代里存放的都是朝生夕死的对象,于是我们来监控下对象,看看哪些对象占用的内存最大,通过监控我发现占用内存最大的就是byte[],那么byte[]对象又是哪里来的呢?
    在这里插入图片描述
    继续分析定位到一个方法:java.awt.image.RenderedImage.getData,看来byte[]就是这个方法生成的。
    在这里插入图片描述
    打开方法的调用栈,发现原来了是我们的一个图片转webp的工具类用到了这个方法。
    在这里插入图片描述

四、总结

综上,从发现问题到定位问题我们经过了下面的步骤

  1. 定位导致cpu飙升的服务
  2. 查看GC情况,判断是否是因为GC频繁导致的CPU飙升
  3. 查看服务内存配置,观察内存配置是否合理
  4. 升级服务内存配置看是否能够降低GC频率,进而降低CPU
  5. 借助工具分析内存实时情况
  6. 定位占用内存较大的对象
  7. 找到生成该对象的方法调用栈,进而定位具体有问题的代码
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值