【工作中问题解决实践 十二】线上如何排查CPU100%的情况

当我们把服务发布到服务器器,可能会因为一些问题造成我们的服务器CPU被打满甚至超过100%,那如果我们想知道到底上在做什么操作导致CPU持续过高呢?因为在线上只能通过日志看问题,或者排查到哪个进程或者哪个线程持续占用CPU。然后才能找到具体问题在哪里才能进行解决,具体排查过程

排查过程

无论是什么原因导致的,一定会体现在具体的进程和线程上,所以开始从进程入手,找到最大的线程

  1. 执行top -c命令:查看所有进程占系统CPU的排序。极大可能排第一个的就是咱们的java进程(COMMAND列)。PID那一列就是进程号。可以看到,有一个 Java 程序此时 CPU 占用量达到了 98.8%,此时我们可以复制该进程 id9,并且使用如下命令查看该进程的各个线程运行情况 找高CPU进程
top - 08:31:10 up 30 min,  0 users,  load average: 0.73, 0.58, 0.34
KiB Mem:   2046460 total,  1923864 used,   122596 free,    14388 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.  1192352 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    9 root      20   0 2557160 288976  15812 S  98.0 14.1   0:42.60 java
  1. 执行top -Hp 进程号命令:查看java进程下的所有线程占CPU的情况top -Hp PID 9,可以看到,在进程为 9 的 Java 程序中各个线程的 CPU 占用情况,接下来我们可以通过 jstack 命令查看线程 id 为 10 的线程为什么耗费 CPU 最高 找高CPU线程
top - 08:31:16 up 30 min,  0 users,  load average: 0.75, 0.59, 0.35
Threads:  11 total,   1 running,  10 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.5 us,  0.6 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   2046460 total,  1924856 used,   121604 free,    14396 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.  1192532 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
   10 root      20   0 2557160 289824  15872 R 79.3 14.2   0:41.49 java
   11 root      20   0 2557160 289824  15872 S 13.2 14.2   0:06.78 java
  1. 执行printf "%x\n 10命令 :后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,咱们需要把线程号转成16进制。例如,printf "%x\n 10打印:a,那么在jstack中线程号就是0xa.转换获取操作系统线程ID
  2. 执行 jstack 进程号 | grep 线程ID 查找某进程下线程ID(jstack堆栈信息中的nid)=0xa的线程状态。如果"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable,第一个双引号圈起来的就是线程名,如果是VM Thread这就是虚拟机GC回收线程了获取该进程快照并grep到该线程,查看线程状态
"main" #1 prio=5 os_prio=0 tid=0x00007f8718009800 nid=0xb runnable [0x00007f871fe41000]
   java.lang.Thread.State: RUNNABLE
    at com.aibaobei.chapter2.eg2.UserDemo.main(UserDemo.java:9)

"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable
  1. 执行jstat -gcutil 进程号 统计间隔毫秒 统计次数(缺省代表一致统计),查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大确认Full GC 也可以使用jmap -heap 进程ID查看一下进程的堆内从是不是要溢出了,特别是老年代内从使用情况一般是达到阈值(具体看垃圾回收器和启动时配置的阈值)就会进程Full GC。【如果是虚拟机线程】统计gc情况,判断是否是full GC过多
root@8d36124607a0:/# jstat -gcutil 9 1000 10
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   0.00  75.07  59.09  59.60   3259    0.919  6517    7.715    8.635
  0.00   0.00   0.00   0.08  59.09  59.60   3306    0.930  6611    7.822    8.752
  0.00   0.00   0.00   0.08  59.09  59.60   3351    0.943  6701    7.924    8.867
  0.00   0.00   0.00   0.08  59.09  59.60   3397    0.955  6793    8.029    8.984
  1. 执行jmap -dump:format=b,file=filename 进程ID”,导出某进程下内存heap输出到文件中。可以通过mat工具查看内存中有哪些对象比较多。公司封装后,我们用的命令是heap dump【如果是虚拟机线程】heap dump下虚拟机快照,查看对象树判断

不同的问题结论排查到同的阶段就会有结论

问题定位

针对以上各个步骤,大致排查到某些步骤后就可以大致定位具体原因了

1 内存消耗过大,导致Full GC次数过多

一直排查,执行了步骤1-5

  • 步骤2明确为虚拟机线程】多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程
  • 步骤5查看GC情况】通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加。

确定是Full GC, 接下来找到具体原因:

  • 步骤6查看堆Dump文件】使用MAT工具分析,如果生成大量的对象,导致内存溢出,查看具体内存对象占用情况。
  • 如果对象占用不算高,但是Full GC次数还是比较多,此时可能是代码中手动调用 System.gc()导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

2 代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢

一直排查,执行了步骤1-4

  • 步骤2明确为非虚拟机线程
  • 步骤4查看线程快照情况】可直接定位到代码行。问题原因有某些复杂算法,甚至算法BUG,无限循环递归等。

3 由于锁使用不当,导致死锁

一直排查,执行了步骤1-4

  • 步骤2明确为非虚拟机线程
  • 步骤4查看线程快照情况】如果有死锁,会直接提示。关键字:deadlock 会打印出业务死锁的位置

在这里插入图片描述

4 不定期出现的接口耗时现象

对于这种情况,比较典型的例子就是,我们某个接口访问经常需要 2~3s 才能返回。这是比较麻烦的一种情况,因为一般来说,其消耗的 CPU 不多,而且占用的内存也不高,也就是说,我们通过【1-4】排查是无法解决这种问题的。而且由于这样的接口耗时比较大的问题是不定时出现的,这就导致了我们在通过 jstack 命令即使得到了线程访问的堆栈信息,我们也没法判断具体哪个线程是正在执行比较耗时操作的线程。对于不定时出现的接口耗时比较严重的问题,我们的定位思路基本如下:首先找到该接口,通过压测工具不断加大访问力度,如果说该接口中有某个位置是比较耗时的,由于我们的访问的频率非常高,那么大多数的线程最终都将阻塞于该阻塞点

  • 通过压测工具不断加大接口访问力度
  • 一直排查,执行了步骤1-4:查看线程快照信息,大量线程都会阻塞在该点
"http-nio-8080-exec-4" #31 daemon prio=5 os_prio=31 tid=0x00007fd08d0fa000 nid=0x6403 waiting on condition [0x00007000033db000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)-》期限等待

    at java.lang.Thread.sleep(Native Method)

    at java.lang.Thread.sleep(Thread.java:340)

    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)

    at com.*.user.controller.UserController.detail(UserController.java:18)-》业务代码阻塞点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/487474.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于java+springboot+vue实现的医院门诊信息管理系统(文末源码+Lw+ppt)23-325

摘 要 系统根据现有的管理模块进行开发和扩展,采用面向对象的开发的思想和结构化的开发方法对医院门诊信息的现状进行系统调查。采用结构化的分析设计,该方法要求结合一定的图表,在模块化的基础上进行系统的开发工作。在设计中采用“自下而…

c++翁恺

1、面向对象 Data:杯子的属性 Opera:杯子提供的服务 老师上课: C:按流程执行 C:定一个教室,有很多学生,投影仪,灯,每个学生反映不一样。 这个场景有什么东西&#xff0c…

SSM整合遇到的问题,非常干货,希望能帮助到您~

你们好,我是金金金。 无法自动装配 配置类已经配置了扫描 那是什么原因导致? 解决 很明显位置都不在一起,需要更改。 结果类型不匹配select id“selectEmployeeByCondition” 什么原因导致? 这个是因为我建立了很多子模块 名字…

基于tcp协议的网络通信(将服务端守护进程化)

目录 守护进程化 引入 介绍 如何实现 思路 接口 -- setsid 注意点 实现代码 daemon.hpp log.hpp 运行情况 前情提要 -- 前后台任务介绍(区别命令),sessionsid介绍,session退出后的情况(nuhup,终端进程控制组),任务进程组概念,任务与进程组的关系,-bash介绍-CSDN博客…

最详细的ubuntu 安装 docker教程

Docker是一种流行的容器化平台,它能够简化应用程序的部署和管理。本文将介绍在Ubuntu操作系统上安装Docker的步骤,以便我们可以开始使用Docker来构建和运行容器化应用程序。 系统版本 本文以Ubuntu20.05系统为例安装docker,Ubuntu官方下载地…

输出当前时间

用途:在项目中一些属性中设置当前时间 实例代码 import java.time.LocalDateTime; import java.time.format.DateTimeFormatter;public class time {public static void main(String[] args){LocalDateTime china LocalDateTime.now(); DateTimeFormatter forma…

函数作用域和块级作用域:JavaScript中的变量作用域解析

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

知识图谱操作的探索与利用

目录 前言1 搜索(Search)1.1 基于关键词搜索1.2 属性搜索1.3 模式匹配 2 过滤(Filtering)2.1 属性过滤2.2 关系过滤 3 引导(Guidance)3.1 相关实体推荐3.2 路径推荐 4 合并(Merging)…

OpenLayers基础教程——WebGLPoints图层样式的设置方法

1、前言 前一篇博客介绍了如何在OpenLayers中使用WebGLPoints加载海量数据点的方法,这篇博客就来介绍一下WebGLPoints图层的样式设置问题。 2、样式运算符 在VectorLayer图层中,我们只需要创建一个ol.style.Style对象即可,WebGLPoints则不…

【c++】类和对象(三)构造函数和析构函数

🔥个人主页:Quitecoder 🔥专栏:c笔记仓 朋友们大家好,本篇文章我们带来类和对象重要的部分,构造函数和析构函数 目录 1.类的6个默认成员函数2.构造函数2.1构造函数其他特性 3.构析函数3.1特性:…

03课程发布模块课程预览

课程预览界面 界面原型 课程在发布前需要运营方进行审核,作为课程制作方即教学机构发布课程前可以通过课程预览功能查看课程详情界面,及时修改页面中的内容排版和违规问题 课程预览就是把课程的相关信息进行整合然后在课程预览界面进行展示&#xff0…

为jupyter安装和使用不同的python版本

安装好jupyter后,发现为默认的python3,想要切换到python3.10, 1.创建新环境python310 conda create -n python310 python3.10 2.进入新环境python310 conda activate python310 3.下载jupyter notebook conda install jupyter notebook…

802.1X网络访问控制协议

802.1X是一种由IEEE(电气和电子工程师协会)制定的网络访问控制协议,主要用于以太网和无线局域网(WLAN)中基于端口的网络接入控制。802.1X协议通过认证和授权机制,确保只有合法的用户和设备才能够接入网络&a…

Facebook如何使用增强技术提升广告效果?

AR in AD - case study 脸书2021年宣布了引入AR的新方法,以推动其应用套件中的产品发现和购买。但他们首先考虑是技术。据脸书称,技术一直是增强现实在其应用程序中更广泛使用的主要障碍。这就是为什么它现在正在做出改变,使企业主和广告商更…

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

作者:董伟 简介 SystemUI应用是OpenHarmony中预置的系统应用,为用户提供系统相关信息展示及交互界面,包括系统状态、系统提示、系统提醒等,例如系统时间、电量信息。 本文主要分析batterycomponent、clockcomponent、wificompo…

2024年3月26日 十二生肖 今日运势

小运播报:2024年3月26日,星期二,农历二月十七 (甲辰年丁卯月己丑日),法定工作日。 红榜生肖:鸡、鼠、猴 需要注意:马、狗、羊 喜神方位:东北方 财神方位:…

[HGAME 2023 week2]Designer

[HGAME 2023 week2]Designer 考点:XSS跨站脚本攻击,模板注入 代码审计 function auth(req, res, next) {const token req.headers["authorization"]if (!token) {return res.redirect("/")}try {const decoded jwt.verify(token,…

登录注册界面

T1、编程设计理工超市功能菜单并完成注册和登录功能的实现。 显示完菜单后&#xff0c;提示用户输入菜单项序号。当用户输入<注册>和<登录>菜单序号时模拟完成注册和登录功能&#xff0c;最后提示注册/登录成功并显示注册信息/欢迎XXX登录。当用户输入其他菜…

【随笔】Git -- 基本概念和使用方式(五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

相机标定 手眼标定 网页版

欢迎使用&#xff0c;请移步ipv6 site (jah10527.github.io)