前言

前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨。

其实早在去年我也处理过类似的问题,并记录下来:《一次生产 CPU 100% 排查优化实践》

不过本次问题产生的原因却和上次不太一样,大家可以接着往下看。

问题分析

收到邮件后我马上登陆那台服务器,看了下案发现场还在(负载依然很高)。

于是我便利用这类问题的排查套路定位一遍。


首先利用 top -c 将系统资源使用情况实时显示出来 (-c 参数可以完整显示命令)。

接着输入大写 P 将应用按照 CPU 使用率排序,第一个就是使用率最高的程序。

果不其然就是我们的一个 Java 应用。

这个应用简单来说就是定时跑一些报表使的,每天凌晨会触发任务调度,正常情况下几个小时就会运行完毕。


常规操作第二步自然是得知道这个应用中最耗 CPU 的线程到底再干嘛。

利用 top -Hp pid 然后输入 P 依然可以按照 CPU 使用率将线程排序。

这时我们只需要记住线程的 ID 将其转换为 16 进制存储起来,通过 jstack pid >pid.log 生成日志文件,利用刚才保存的 16 进制进程 ID 去这个线程快照中搜索即可知道消耗 CPU 的线程在干啥了。

如果你嫌麻烦,我也强烈推荐阿里开源的问题定位神器 arthas 来定位问题。

比如上述操作便可精简为一个命令 thread -n 3 即可将最忙碌的三个线程快照打印出来,非常高效。

更多关于 arthas 使用教程请参考官方文档。

由于之前忘记截图了,这里我直接得出结论吧:

最忙绿的线程是一个 GC 线程,也就意味着它在忙着做垃圾回收。

GC 查看

排查到这里,有经验的老司机一定会想到:多半是应用内存使用有问题导致的。

于是我通过 jstat -gcutil pid 200 50 将内存使用、gc 回收状况打印出来(每隔 200ms 打印 50次)。

从图中可以得到以下几个信息:

  • Eden 区和 old 区都快占满了,可见内存回收是有问题的。
  • fgc 回收频次很高,10s 之内发生了 8 次回收((866493-866485)/ (200 *5))。
  • 持续的时间较长,fgc 已经发生了 8W 多次。

内存分析

既然是初步定位是内存问题,所以还是得拿一份内存快照分析才能最终定位到问题。

通过命令 jmap -dump:live,format=b,file=dump.hprof pid 可以导出一份快照文件。

这时就得借助 MAT 这类的分析工具出马了。

问题定位

通过这张图其实很明显可以看出,在内存中存在一个非常大的字符串,而这个字符串正好是被这个定时任务的线程引用着。

大概算了一下这个字符串所占的内存为 258m 左右,就一个字符串来说已经是非常大的对象了。

那这个字符串是咋产生的呢?

其实看上图中的引用关系及字符串的内容不难看出这是一个 insertSQL 语句。

这时不得不赞叹 MAT 这个工具,他还能帮你预测出这个内存快照可能出现问题地方同时给出线程快照。

最终通过这个线程快照找到了具体的业务代码:

他调用一个写入数据库的方法,而这个方法会拼接一个 insert 语句,其中的 values 是循环拼接生成,大概如下:

1    <insert id="insert" parameterType="java.util.List">
2        insert into xx (files)
3        values
4        <foreach collection="list" item="item" separator=",">
5            xxx
6        </foreach>
7    </insert>

所以一旦这个 list 非常大时,这个拼接的 SQL 语句也会很长。

通过刚才的内存分析其实可以看出这个 List 也是非常大的,也就导致了最终的这个 insert 语句占用的内存巨大。

优化策略

既然找到问题原因那就好解决了,有两个方向:

  • 控制源头 List 的大小,这个 List 也是从某张表中获取的数据,可以分页获取;这样后续的 insert 语句就会减小。
  • 控制批量写入数据的大小,其实本质还是要把这个拼接的 SQL 长度降下来。
  • 整个的写入效率需要重新评估。

总结

本次问题从分析到解决花的时间并不长,也还比较典型,其中的过程再总结一下:

  • 首先定位消耗 CPU 进程。
  • 再定位消耗 CPU 的具体线程。
  • 内存问题 dump 出快照进行分析。
  • 得出结论,调整代码,测试结果。

最后愿大家都别接到生产告警。

你的点赞与分享是对我最大的支持

x

java获取cpu使用率_再一次生产 CPU 高负载排查实践相关推荐

  1. qt获取cpu使用率_又一次生产 CPU 高负载排查实践

    以下文章来源于crossoverJie ,作者crossoverJie 前言 前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨. 其 ...

  2. cpu使用率_微软:Windows 10的高CPU使用率问题已解

    本文转自快科技 微软今天给出公告称,Windows 10的一个更新补丁导致CPU使用率过高的错误已经解决,不过暂时他们还没有给出补丁来解决. 至于为何引起CPU占用率过高的问题,微软承认输入法编辑器( ...

  3. 高cpu_再一次生产 CPU 高负载排查实践

    (给ImportNew加星标,提高Java技能) 作者:crossoverJie segmentfault.com/a/1190000019507028 前言 前几日早上打开邮箱收到一封监控报警邮件: ...

  4. 又一次生产 CPU 高负载排查实践

    本文经授权转载自微信公众号:crossoverJie 前言 前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨. 其实早在去年我也处理 ...

  5. cpu使用率_线程CPU使用率到底该如何计算?

    来源:公众号[鱼鹰谈单片机]作者:鱼鹰OspreyID   :emOsprey这篇笔记有如下内容:1.为什么需要计算各个线程的CPU使用率?2.该如何计算线程CPU使用率?3.FreeRTOS线程计算 ...

  6. 查看cpu使用率_腾讯游戏开发工程师:Linux 机器 CPU 毛刺问题排查

    作者:jasonzxpan,腾讯 IEG 运营开发工程师 本文排查一个Linux 机器 CPU 毛刺问题,排查过程中不变更进程状态.也不会影响线上服务,最后还对 CPU 毛刺带来的风险进行了分析和验证 ...

  7. 【Mysql】记一次生产CPU使用率突然剧增,内存一直飚高不下故障问题排查 (com.mysql.jdbc.MysqlIO.readFully)

    问题: 生产某一小时内CPU使用率突然剧增,内存一直飚高不下,系统响应速度变慢 按照解决问题惯例,由于未影响到业务,但超过监控红线了, 快速分析问题,jstack抓堆栈日志定位如下,其后平滑重启了暂时 ...

  8. io密集型和cpu密集型_和小胖一起理解CPU负载和利用率

    作者:小胖前言 凌晨一点,正整着炸鸡的小胖,微信一呼"你的服务器CPU持续超载 - " 麻溜的连上服务器,先把CPU负载摁下来.仔细一想,最近1分钟平均负载很大,但CPU利用率却≤ ...

  9. linux服务器cpu飙高问题排查实践记录

    问题描述: 测试环境大量请求出现504错误 1.第一反应上服务器看看资源消耗情况(登陆服务器时出现卡顿) 2.使用top命令查看cpu消耗情况,查看结果如下: 很明显cpu使用率已经满了(两核CPU) ...

最新文章

  1. MAVEN的使用入门
  2. java常见_关于Java的常见误解
  3. 学习日志---矩阵表示及特殊矩阵压缩
  4. Python 脚本相关知识
  5. 告别枯燥,这本插画式 Python 书难怪销量 70W+
  6. 【COGS 1873】 [国家集训队2011]happiness(吴确) 最小割
  7. 【eclipse反编译工具】最好的反编译工具
  8. acm竞赛题库与解析
  9. D365几个功能开发思路
  10. 英语基础语法学习笔记 2
  11. kafka linux 脚本测试,kafka shell命令操作
  12. 小程序该怎么去做引流和变现呢
  13. 百度账号管理静态页面
  14. ZigBee网络拓扑结构
  15. unity实现鼠标打飞碟(Hit UFO)游戏
  16. 华为服务器网口作用,设置网口模式(mode)
  17. Docker image 是啥?
  18. 随笔 数据库敏感数据加密存储
  19. 嘿嘿,插播消息,最新一期的流言终结者
  20. SQL Studio:一款纯Web化SQL开发工具,关键是免安装还免费!

热门文章

  1. C++ 基类和派生类的构造函数
  2. MySQL 条件查询
  3. 数据线给电脑联网是什么原理_物联网孵化的产物——条码扫描器
  4. openwrt dhcp 无法获取ip_电脑的 ip 是怎么来的呢?我又没有配置过
  5. vue 拖动 datatransfer 问题_electron-vue跨平台桌面应用开发实战教程(四)——窗口样式amp;打开新窗口...
  6. hadoop yarn 获取日志_Hadoop YARN配置参数剖析(2)—权限与日志聚集相关参数
  7. java中methods方法_java中Class.getMethod方法
  8. parallelstream启动的线程数_高并发与多线程网络学习笔记(三)线程组和线程池
  9. 将json字符串转换为json对象
  10. 测试人员做到这几点,线上80%的BUG将落入你手,企业将避免重大风险