【经验分享】日常开发中的故障排查经验分享(一)

目录

  • 简介
  • CPU飙高问题
    • 1、使用JVM命令排查CPU飙升100%问题
    • 2、使用Arthas的方式定位CPU飙升问题
    • 3、Java项目导致CPU飙升的原因有哪些?如何解决?
  • OOM问题(内存溢出)
    • 1、如何定位OOM问题?
    • 2、OOM问题产生原因
  • 死锁问题的定位
  • 频繁Full GC问题
    • 1、频繁FullGC会导致哪些问题
    • 2、如何排查
    • 3、导致频繁FullGC的原因
  • 内存泄露问题的排查
  • 磁盘空间不足,如何排查Linux中的大文件位置
  • 尾声

简介

众所周知,咱们程序员在日常工作中肯定少不了会碰到系统故障、系统缓慢等问题,该笔记是我在工作中对一些OOM、CPU飙高、内存泄露等问题的排查笔记,现在分享出来,因为平时开发中我就是根据这些步骤进行排查的,没有附图,不喜勿喷。

CPU飙高问题

1、使用JVM命令排查CPU飙升100%问题

  • 第一步:查看系统进程CPU使用率,首先使用【top】命令列出系统各个进程的资源占用,查看是哪个进程的CPU不对劲,看 %CPU 这个数值,然后找到对应的进程ID号。

  • 第二步:查看当前进程号的线程CPU使用率,使用【top -Hp 进程ID】命令查看第一步查询出来的进程ID内的线程CPU使用情况。

  • 第三步:找到CPU使用率高的线程并将PID转化为十六进制,将这个PID转化为十六进制【printf ‘0x%x’ PID】。

  • 第四步:输出当前进程内的该线程的堆栈信息,有两种方式,

    • 一种是使用jstack命令将之前的那个CPU高的进程输出到一个txt文件中【jstack 1677 > 1.txt】,然后使用vim或者grep根据十六进制去搜索。
    • 另外一种就是直接使用【jstack 进程ID | grep 16进制的线程PID -A20】这个命令直接输出后20行,找到对应代码位置。
  • 最后定位到具体业务代码的位置,我们去找到对应代码修改就行了

2、使用Arthas的方式定位CPU飙升问题

  • 第一步:需要去下载arthas的jar包:wget https://arthas.aliyun.com/arthas-boot.jar

  • 第二步:启动arthas:java -jar arthas-boot.jar

  • 第三步:其实启动的时候就显示了CPU高的类了,但是我们可以通过命令查看:
    查看系统整体运行情况:dashboard
    查看最繁忙的线程【可以显示具体代码位置】:thread -n 1
    查看繁忙的线程具体的代码:jad 【上面查询出来的包名+类名】
    找到代码位置后,根据实际业务场景去做修改就行了。

3、Java项目导致CPU飙升的原因有哪些?如何解决?

CPU飙高的原因:

1、代码中存在大量的循环、递归或者重复计算等操作,导致程序运行时消耗大量的CPU资源。
2、代码中需要处理大量的数据,如果数据量过大或者处理不当,会导致CPU占用过高。
3、频繁的IO操作,代码中涉及到频繁访问数据库、频繁读写文件等操作,由于IO操作比较耗时,导致CPU占用过高。
4、代码中创建大量线程并处于长时间忙碌状态,会导致CPU占用过高。
5、多线程之间互相竞争同一资源,导致CPU不断切换线程从而消耗大量资源,会导致CPU占用过高。
6、JVM问题:配置不当或者性能问题导致CPU过高。
7、内存泄露也有可能导致CPU飙高。内存泄露的程序,JVM频繁进行FullGC尝试释放内存空间,进而会导致CPU飙升,内存泄露过多,造成可回收内存不足,程序申请内存失败,结果就是内存溢出。

如何解决:

  • 优化代码逻辑,尽量减少重复计算和不必要的循环
  • 合理处理大量数据,可以使用分页或者分批处理的方式。
  • 检查并发处理的线程数量,合理控制线程的创建和销毁。
  • 对JVM进行适当的配置和调优,如调整堆大小、垃圾回收策略等。

还是要根据具体的业务场景来进行优化。

OOM问题(内存溢出)

1、如何定位OOM问题?

一般出现OOM问题,java.lang.OutOfMemoryError:Java heap space或者其他,我们都是通过dump文件去定位问题。

方式一(生产环境经常使用的方式):
我们工作里面都是在启动脚本里面提前加入:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump/
这个配置信息来提前预防,当出现OOM问题时,会将当前内存输出一个dump文件放入到指定的目录下(我这里是放到/logs/dump/目录下),然后将文件下载下来以后,通过MAT或者JProfile或者visualvm工具加载dump文件进行调试,查看最多跟业务有关的对象,然后找到GCRoot,查看线程栈的输出定位到具体代码位置。

方式二:使用命令主动导出
需要导出dump文件:【jmap -dump:format=b,file=1.hprof PID】或者通过Arthas工具;

2、OOM问题产生原因

  • 一次性申请了太多的对象:比如说做一些列表的查询,一次性把所有的数据都给弄出来了,未做分页,假如数据达到了千万级,都查出来放入到List集合当中,有可能造成内存溢出。解决:更改申请对象的数量,比如说分页

  • 内存资源耗尽未释放:比如说使用线程或者使用数据库查询,在高并发情况下不断创建线程,或者不断的创建数据库连接,但是又没有去释放,久而久之就会溢出,比如说流创建比较多,但是没有去关闭。使用池化技术去优化代码

  • 本身资源不够:就是给堆分配的内存不够,因为在业务中可能会存在要创建大对象支撑业务正常运行,可以通过【jmap -heap PID :查看堆信息】。

  • 内存泄露导致内存不够,最终OOM。

死锁问题的定位

通过arthas方式定位:

通过arthas的thread命令,使用【thread -b】命令输出线程的统计信息,BLOCKED表示目前阻塞的线程数,命令执行后会直接输出造成死锁的线程ID和具体的代码位置以及当前线程一共阻塞的线程数量。

通过命令方式定位:

1、使用【jps -l】命令列出所有进程;

2、使用【jstack 进程id | grep ‘deadlock’ -A 100】命令,通过jstack命令和死锁关键字打印出这个进程出现死锁的堆栈信息。里面的信息会打印出代码的具体位置,是哪些线程造成死锁。

3、根据打印出来的堆栈信息,找到代码具体位置,然后根据业务去解决。

频繁Full GC问题

1、频繁FullGC会导致哪些问题

  • 系统卡顿:Full GC需要对整个堆进行扫描和处理,这个过程会导致应用程序的执行暂停。在这段时间内,应用程序无法响应用户请求,可能造成用户体验的下降或业务中断。

  • 长时间延迟:Full GC的执行时间较长,特别是当堆内存较大时。如果Full GC发生的频率较高或执行时间过长,可能会导致系统的响应时间变慢,影响系统的性能和吞吐量。

  • 内存占用过高从而影响其他服务正常运行:Full GC的执行通常需要消耗大量的CPU和内存资源。如果Full GC发生频繁且占用大量资源,可能会导致系统的资源消耗过高,从而影响其他应用程序或服务的正常运行。

  • 系统不稳定:Full GC执行期间,应用程序可能处于一个不可预测的状态,因为可能会触发一些不符合预期的行为。这可能导致应用程序的异常行为、内存泄漏等问题。

2、如何排查

详细的我写在内存泄露那块的排查了。

1、首先找到对应的服务,使用jps找到线程PID;

2、使用【jstat -gcutil PID 1000 10 】查看GC情况,FGC指的是Full GC数量

timestamp     S0     S1     E       O     M     CCS    YGC     YGCT    FGC    FGCT     GCT


timestamp:是距离JVM启动的时间
S0、S1、E:分别是新生代的两个Survivor和Eden
O:是老年代区域
M:是Metaspace,元空间
CCS:使用压缩比例
YUC、YGCT:分别是新生代GC的次数和时间
FGC、FGCT:分别是老年代GC的次数和时间
GCT:GC的总时间

3、使用jstat -gccause查看额外输出上次GC的原因

4、使用jmap -dump:format=b,file=heapdump 线程ID;导出dump文件

5、使用MAT或者JProfile工具进行分析

3、导致频繁FullGC的原因

  • 大对象,系统一次性加载了过多数据到内存:导致大对象直接进入到老年代;

  • 内存泄露,频繁创建了大量对象,但是无法被回收,先引发Full GC,最后导致OOM。

  • 程序频繁生成一些长声明周期的对象,当这些对象的平均年龄超过分代年龄时就会进入到老年代,最后老年代空间不够导致Full GC。

  • 程序BUG。

  • 代码里面显式调用了System.gc()。

  • JVM参数设置问题,包括总内存大小、新生代、老年代的大小、Eden区和幸存者S区的大小、元空间大小和垃圾回收算法等。

内存泄露问题的排查

不解决内存泄露会造成的影响:

  • 现象一:进程可用内存会变少导致结果就是OOM,发生了这个问题后可能就会想到堆内存不够大,于是就将-Xmx参数调大,然后重启应用,但是过了一段时间后,OOM还是出现了。这个时候堆内存参数无法再调大,就只能每隔一段时间重启一下应用。

  • 现象二:请求响应时间变长,这是因为频繁发生FullGC会暂停其他所有线程【Stop the world】造成的。

如何排查?

1、使用【jps -l】命令定位到进程号,因为线上如果有应用出现OOM,那么这个应用的进程号用jps肯定能找到。

2、使用【jstat -gcutil -t -h8 进程ID 1000】每隔1000ms打印一次该进程内存内GC活动情况,每8行输出一个行头信息。

root@8d36124607a0:/# jstat -gcutil -t -h8  进程ID   1000
 timestamp     S0     S1     E       O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
   29.1       32.81   0.00  23.48  85.92  92.84  89.60   14      0.419    0     0.000    0.419
   30.1       32.81   0.00  78.12  85.92  92.84  89.60   14      0.419    0     0.000    0.419
   31.1       0.00    0.00  22.70  91.74  92.80  89.60   15      0.443    1     0.233    0.676
  
timestamp:是距离JVM启动的时间
S0、S1、E:分别是新生代的两个Survivor和Eden
O:是老年代区域
M:是Metaspace,元空间
CCS:使用压缩比例
YUC、YGCT:分别是新生代GC的次数和时间
FGC、FGCT:分别是老年代GC的次数和时间
GCT:GC的总时间

3、观察以上GC参数,可以发现老年代内存O的占用率根本没有下降,说明有的对象无法被回收,也有可能这些对象是长期有用的。

4、使用【jmap -dump:live,format=b,file=/log/dempFile/heap.bin 进程ID 】dump出内存快照到指定目录下,然后将这个heap.bin文件下载下来,然后使用MAT工具或者JProfile工具导入dump文件进行排查,找到【Leak Suspects】选项,工具会自动帮我们列出所有可能发生内存泄露的对象以及对象的个数,之后找到代码的对应位置根据业务进行修改即可。
在这里插入图片描述

造成内存泄露的情况(列举几种):

  • 资源未关闭或释放导致内存泄露:在创建了各种连接【比如:数据库链接、网络IO和IO连接】,使用后未调用close()进行显式关闭,GC不会自动回收这些连接,大量对象未进行关闭就会引起内存泄露。

  • 使用了ThreadLocal未进行remove()引发的内存泄露。

  • 在代码中使用了大量的静态集合类:比如将HashMap、LinkedList等容器声明为静态,使得它们的生命周期与程序一致,容器内的元素在程序结束前不能被释放从而造成内存泄露。长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。

  • 单例模式:单例对象在初始化后会以静态变量的方式在JVM的整个声明周期中存在,如果单例对象持有外部引用,那么这个外部对象将不能被GC回收导致内存泄露。

  • 定义变量的作用于大于其适用范围:当设置一个全局变量在使用完未将其设置为null,可能会造成内存泄漏。

磁盘空间不足,如何排查Linux中的大文件位置

1、使用du命令去排查(常用):du命令可以查看磁盘空间的使用情况,自然也可以用来查看磁盘上占用空间较多的文件和文件夹。

# 查看当前目录下最大的前几个文件
du -ahx . | sort -rh | head -5
#查看根目录下所有文件的大小
du -sh /*  

2、使用find命令排查

# 如果要找前10个大文件
find $home -type f -printf '%s %p\n' | sort -nr | head -10     

尾声

其实线上问题的排查,一般就是top、free、df三连,然后再根据现象去定位是什么问题。

  • top命令:是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。进程状态显示和控制,每5s中自动刷新一次(动态显示)。
  • df指令:查看磁盘的使用率。
  • free指令:可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区。

JVM常用的几个命令:

jps:查看正在运行的Java进程id
jstat:查看JVM内存的统计信息
jstack:打印JVM线程快照
jmap:导出内存映像文件&内存使用情况
.....

以上就是我平时开发中遇到的一些比较棘手的问题排查经验,没有带图片,不喜勿喷,后续等Arthas用熟了以后,再写一篇排查经验分享(二)的文章。

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

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

相关文章

SQL Server 存储过程 触发器 事务处理

CSDN 成就一亿技术人! 难度指数:* * CSDN 成就一亿技术人! 目录 1. 存储过程的作用 创建存储过程 2. 触发器 触发器的种类 insert触发器 update触发器 delete触发器 测试 3. 事务 开始事务 提交事务 回滚事务 举个实例 在 SQ…

深度学习在自然语言处理中的应用

深度学习在自然语言处理中的应用 一、引言 随着人工智能技术的飞速发展,自然语言处理(NLP)作为其重要分支,已经在诸多领域取得了令人瞩目的成果。深度学习作为当前最炙手可热的技术,为NLP带来了革命性的变革。本文将…

红队打靶练习:MISDIRECTION: 1

信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.12.128 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.12.1 00:50:56:c0:00:08 …

【计算机毕业设计】SSM在线宿舍管理系统

项目介绍 本项目包含管理员、宿舍管理员、学生三种角色; 管理员角色包含以下功能: 管理员登录,院系管理,专业管理,年级管理,班级管理,学生设置,宿舍管理员管理,宿舍楼管理,宿舍管理,床位管理,学生入住登记,学生退房管理等功能。 宿舍管理员角色包含以…

如何在 Linux 中配置 firewalld 规则

什么是FirewallD “firewalld”是firewall daemon。它提供了一个动态管理的防火墙,带有一个非常强大的过滤系统,称为 Netfilter,由 Linux 内核提供。 FirewallD 使用zones和services的概念,而 iptables 使用chain和rules。与 ip…

LabVIEW的便携式车辆振动测试分析

随着计算机和软件技术的发展,虚拟仪器正逐渐成为机械工业测试领域的主流。在现代机械工程中,特别是车辆振动测试,传统的测试方法不仅设备繁杂、成本高昂,而且操作复杂。为解决这些问题,开发了一款基于美国国家仪器公司…

【React】echarts-for-react 的使用

文章目录 echarts-for-react :一个简单的 Apache echarts 的 React 封装配置项手册:https://echarts.apache.org/zh/option.html#title 安装依赖 $ npm install --save echarts-for-react# echarts 是 echarts-for-react的对等依赖,您可以使用自己的版本…

新能源汽车冷却系统的水道管口类型有哪些?格雷希尔针对这些管口密封的快速接头有哪些?

对于新能源汽车,不仅电池,还有电机、电控、充电单元部件,都需要处于适宜的工作温度,才能维持整车的正常运行。而这些部件在运行过程中会产生大量的热量,如果不及时散热会对汽车的性能、寿命产生影响,甚至可…

基于ssm西安旅游管理系统论文

摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对西安旅游信息管理的提升&#x…

基于element-ui table组件的二次封装

文章目录 配置数据基础分析封装 el-table-column使用插槽强化结语 相信 element-ui 大家都有所耳闻,table 也是老朋友了,不过有没有在使用他的时候,大家是怎么使用的呢?是直接在官网上cv使用吗?这种方式,我…

2023启示录丨自动驾驶这一年

图片|《老人与海》插图 过去的20年,都没有2023年如此动荡。 大模型犹如一颗原子弹投入科技圈,卷起万里尘沙,传统模式瞬间被夷为平地,在耀眼的白光和巨大的轰鸣声之下,大公司、创业者、投资人甚至是每一位观…

裕泰微YT8521SH PHY芯片在uboot下的代码适配(一)

文章目录 支持的工作模式自协商模式下改变 PHY 支持的速度和双工能力 RGMII 配置通过 POS 设置 RX_delay通过寄存器加长 RX_delayTX_delay 的设置驱动能力的设置 LED 灯配置硬件电路设计相关问题快速上下电的要求上电复位时序要求 YT8521SC/SH 是一款单口千兆以太网 PHY。 支持…

OSPF ROUTER-ID-新版(15)

目录 整体拓扑 操作步骤 1.INT 验证Router-ID选举规则 1.1 查看路由器Router-ID 1.2 配置R1地址 1.3 查看R1接口信息 1.4 查看R1Router-ID 1.5 删除接口IP并查看Router-ID 1.6 手工配置Router-ID 2.基本配置 2.1 配置R1的IP 2.2 配置R2的IP 2.3 配置R3的IP 2.4 配…

数据库管理-第128期 2023总结(202301229)

数据库管理-第128期 2023总结(202301229) 到了2023年的最后一个工作日,也该对即将过去的2023年做一个小小的总结: 1 写文章 2023年在CSDN总共写了82篇文章。 2023年4月开始在墨天轮写文章,总共写了75篇文章&#xf…

电子工程师如何接私活赚外快?

对电子工程师来说,利用业余时间接私活是个很常见的技术,不仅可以赚取额外收入,也能提升巩固技术,可以说国内十个工程师,必有五个在接私活养家糊口,如果第一次接私活,该如何做? 很多工…

基于Springboot+vue医院管理系统(前后端分离)

最近有一些读者问我有没有完整的基于SpringbootVue的项目源码,今天给大家整理了一下,无偿分享给大家。 功能: 医生信息管理 换着信息管理 挂号信息管理 药物信息管理 检查项目管理 病床信息管理 排班信息管理 数据统计分析 开发工具…

基于低代码的指尖遐想_1

解决问题或分析事务的思考方法: 1、什么是低代码,或者说现在的低代码能做什么,未来能做什么,其存在的合理性是什么? 回答这个问题的本质是搜集信息,公开的或非公开的。 答:低代码主要分为广义…

视频号三年:质疑红利,理解红利,抄底红利

“去年刚进来时,视频号带货配套都还不成熟,团队都不熟悉后台操作,硬是磨合了一个多月,也做好了亏钱的准备。不过前两天刚算了帐,今年 GMV 已经比去年翻了两番。” “22年想靠投流起号,但每次投流计划基本消…

地震烈度速报与预警工程成功案例的经验分享 | TDengine 技术培训班第一期成功落地

近日,涛思数据在成都开设了“国家地震烈度速报与预警工程数据库 TDengine、消息中间件 TMQ 技术培训班”,这次培训活动共分为三期,而本次活动是第一期。其目标是帮助参与者深入了解 TDengine 和 TMQ 的技术特点和应用场景,并学习如…

geemap学习笔记037:分析地理空间数据--坐标格网和渔网

前言 坐标格网(Coordinate Grid)简称“坐标网”,是按一定纵横坐标间距,在地图上划分的格网,坐标网是任何地图上不可缺少的要素之一。下面将详细介绍一下坐标格网和渔网。 1 导入库并显示地图 import ee import geem…