【实战场景】记一次UAT jvm故障排查经历

【实战场景】记一次UAT jvm故障排查经历

  • 开篇词:
  • 干货篇:
      • 1.查看系统资源使用情况
      • 2.将十进制进程号转成十六进制
      • 3.使用jstack工具监视进程的垃圾回收情况
      • 4.输出指定线程的堆内存信息
      • 5.观察日志
      • 6.本地环境复现
  • 总结篇:
  • 我是杰叔叔,一名沪漂的码农,下期再会!

开篇词:

故障背景是客服中心通话历史分表4季度,单表200w+,查询一年的数据量,大分页(查询第20w页的10条数据)查询多次,tomcat卡死,一段时间后,后台其他定时任务,kafaka消费线程恢复正常,tomcat web容器依旧高cpu,具卡无比。

干货篇:

1.查看系统资源使用情况

top -H -p 49339
解释:查看进程49339进程的实时系统资源使用情况,“-H”表示查看进程中所有线程资源占用情况; “-p”指用来指定具体进程号

2.将十进制进程号转成十六进制

printf “%x \n” 49339
解释:转换的目的是让这个线程ID能和jstack输出的线程ID匹配上,因为jstack输出的是十六进制的线程ID

3.使用jstack工具监视进程的垃圾回收情况

jstat -gc 49339 3 5
解释:通过jstat工具查看jvm 垃圾回收情况,“-gc”指定要监视的内容为垃圾回收情况;“3”每隔三秒输出一次监视结果;“5”一共输出5次监视结果。
在这里插入图片描述

其中各参数代表的含义:

  • S0C (Survivor space 0 capacity):第一个幸存区(Survivor space)的容量(以字节为单位)。幸存区用于存放垃圾收集后存活的对象。
  • S1C (Survivor space 1 capacity):第二个幸存区的容量(以字节为单位)。在大多数 JVM 实现中,幸存区有两个,用于在不同的垃圾收集周期之间切换。
  • S0U (Survivor space 0 utilization):第一个幸存区当前已使用的空间大小(以字节为单位)。
  • S1U (Survivor space 1 utilization):第二个幸存区当前已使用的空间大小(以字节为单位)。
  • EC (Eden space capacity):Eden 区的容量(以字节为单位)。Eden 区是 Java 堆的一部分,用于存放新生成的对象。
  • EU (Eden space utilization):Eden 区当前已使用的空间大小(以字节为单位)。
  • OC (Old space capacity):老年代(Old Generation)的容量(以字节为单位)。老年代用于存放存活时间较长的对象。
  • OU (Old space utilization):老年代当前已使用的空间大小(以字节为单位)。
  • MC (Metaspace capacity):元空间(Metaspace,Java 8 引入以替代永久代)的容量(以字节为单位)。元空间用于存放类的元数据。
  • MU (Metaspace utilization):元空间当前已使用的空间大小(以字节为单位)。
  • CCSC (Compressed class space capacity):压缩类空间(Java 8+ 中使用)的容量(以字节为单位)。这个空间用于存放类的元数据,但与元空间分开管理。
  • CCSU (Compressed class space utilization):压缩类空间当前已使用的空间大小(以字节为单位)。
  • YGC (Young GC count):年轻代垃圾收集的次数。
  • YGCT (Young GC time):年轻代垃圾收集所花费的总时间(以秒为单位)。
  • FGC (Full GC count):完全垃圾收集(Full GC,也称作老年代垃圾收集)的次数。
  • FGCT (Full GC time):完全垃圾收集所花费的总时间(以秒为单位)。
  • GCT (Total GC time):垃圾收集所花费的总时间(以秒为单位),包括年轻代和完全垃圾收集的时间。
    请注意,具体的输出参数可能会因 JVM 的版本和配置(如是否启用了压缩指针等)而有所不同。此外,对于 JDK 11 及更高版本,元空间(Metaspace)取代了永久代(PermGen space),因此相关的参数(如 PC 和 PU)在较新版本的 JVM 中不再出现。

4.输出指定线程的堆内存信息

jmap -heap 49339
解释:输出指定线程的堆内存信息
在这里插入图片描述

jstack -l 49339|grep c22a -A 20
解释:时候用jstack工具来输出java进程的线程堆栈信息,并查找包含字符串“c22a”的行,打印其后面的20行
“-l”:指定输出java进程的线程ID;“-A 20”:打印匹配行及其后面的20行

5.观察日志

发现kafka消费线程占用cpu较高,kafka consumer正常epollWait等待kafaka数据,无其他特别异常信息,暂时跳过

6.本地环境复现

更换jdbc连接池至druid,通过dashboard排查分表后的真实sql耗时,中等数据量时,由于分表的存在,limit 20w,20w+10会被重写0,20W+10,以便跨表数据内存排序,数据量大,便造成了慢查询,有可能导致OOM

总结篇:

以下是大致的排查JVM问题的思路:

  1. 初步观察和监控
    查看系统指标:使用系统监控工具(如Linux的top命令或Windows的任务管理器)查看CPU、内存和网络IO等关键指标。
    观察JVM监控工具:使用JDK自带的工具如jConsole、VisualVM或第三方工具(如Arthas)来远程连接并监控JVM的内存使用趋势、线程状态、垃圾回收活动等。
  2. 确定问题类型
    内存问题:观察是否出现OutOfMemoryError(OOM)错误,或者内存使用量异常增长。
    CPU问题:查看CPU使用率是否过高,特别是某个或某些Java线程的CPU占用率异常。
    线程问题:检查是否存在死锁、线程饥饿或线程阻塞等问题。
    垃圾回收问题:分析垃圾回收日志,查看垃圾回收的频率、时间和类型,判断是否存在频繁的Full GC或GC时间过长等问题。
  3. 使用诊断工具
    jstack:用于打印Java线程的堆栈跟踪信息,帮助定位线程问题,如死锁、线程阻塞等。
    示例命令:jstack ,其中是Java进程的进程ID。
    jmap:用于生成堆内存快照和查询堆内存使用情况。
    示例命令:jmap -heap 查看堆内存使用情况,jmap -dump:live,format=b,file=.hprof 生成堆内存快照。
    jstat:用于监视JVM中类的加载、内存、垃圾收集、JIT编译等运行时数据。
    示例命令:jstat -gc 1000每1000毫秒打印一次GC信息。
    jcmd(JDK 1.8+):集成了多个JDK诊断命令的功能,用于执行更复杂的诊断任务。
    示例命令:jcmd Thread.print打印线程信息。
  4. 分析日志和堆内存快照
    分析GC日志:通过GC日志分析垃圾回收的频率、时间、类型和原因,判断是否存在内存泄漏、堆内存设置不合理等问题。
    分析堆内存快照:使用MAT(Memory Analyzer Tool)等内存分析工具分析堆内存快照,查找内存泄漏的源头、大对象占用等。
    查看应用程序日志:检查应用程序日志以获取更多关于错误和异常的上下文信息。
  5. 定位和解决问题
    代码优化:根据分析结果优化代码,减少内存占用、避免内存泄漏、优化数据结构等。
    JVM参数调整:调整JVM启动参数,如堆内存大小(-Xms,-Xmx)、垃圾回收器类型(-XX:+UseG1GC)等,以改善JVM性能。
    升级JDK版本:如果问题是由于JDK的已知bug引起的,考虑升级到更高版本的JDK。
  6. 验证和监控
    验证修复:在开发或测试环境中验证修复是否有效,确保问题得到解决。
    持续监控:在问题解决后,持续监控系统性能,确保没有新的问题出现。

通过以上步骤,可以系统地排查和解决JVM问题,提高系统的稳定性和性能。需要注意的是,排查JVM问题可能需要一定的经验和耐心,因为问题可能由多种因素引起,需要综合考虑各种信息来找到问题的根源。

在这里插入图片描述

我是杰叔叔,一名沪漂的码农,下期再会!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线下促销折扣视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

什么是定时器?

前言👀~ 上一章我们介绍了阻塞队列以及生产者消息模式,今天我们来讲讲定时器 定时器 标准库中的定时器 schedule()方法 扫描线程 手动实现定时器 任务类 存储任务的数据结构 定时器类 如果各位对文章的内容感兴趣的话,请点点小赞&am…

【Python】列表

目录 一、列表的概念 二、列表的创建 1.变量名 [ ] ..... 2.通过Python内置 的I ist类的构造函数来创建列表 三、操作列表元素的方法 1. 修改 2. 增加元素 3. 删除 4. 其他操作 四、遍历列表 五、列表排序 六、列表切片(list slicing) 七、…

值得细读的8个视觉大模型生成式预训练方法

作者:vasgaowei(已授权原创) 编辑: AI生成未来 链接:https://zhuanlan.zhihu.com/p/677794719 大语言模型的进展催生出了ChatGPT这样的应用,让大家对“第四次工业革命”和“AGI”的来临有了一些期待,也作为…

Linux基础指令介绍与详解——原理学习

前言:本节内容标题虽然为指令,但是并不只是讲指令, 更多的是和指令相关的一些原理性的东西。 如果友友只想要查一查某个指令的用法, 很抱歉, 本节不是那种带有字典性质的文章。但是如果友友是想要来学习的,…

深入浅出:npm常用命令详解与实践【保姆级教程】

大家好,我是CodeQi! 在我刚开始学习前端开发的时候,有一件事情让我特别头疼:管理和安装各种各样的依赖包。 那时候,我还不知道 npm 的存在,手动下载和管理这些库简直是噩梦。 后来,我终于接触到了 npm(Node Package Manager),它不仅帮我解决了依赖管理问题,还让我…

Python深度理解系列之【排序算法——冒泡排序】

读者大大们好呀!!!☀️☀️☀️ 👀期待大大的关注哦❗️❗️❗️ 🚀欢迎收看我的主页文章➡️木道寻的主页 文章目录 🔥前言🚀冒泡排序python实现算法实现图形化算法展示 ⭐️⭐️⭐️总结 🔥前…

Apache POI、EasyPoi、EasyExcel

目录 ​编辑 (一)Apache PoI 使用 (二)EasyPoi使用 (三)EasyExcel使用 写 读 最简单的读​ 最简单的读的excel示例​ 最简单的读的对象​ (一)Apache PoI 使用 (二&…

Git 安装

目录 Git 安装 Git 安装 在使用 Git 前我们需要先安装 Git。Git 目前支持 Linux/Unix、Solaris、Mac 和 Windows 平台上运行。Git 各平台安装包下载地址为:http://git-scm.com/downloads 在 Linux 平台上安装(包管理工具安装) 首先&#xff0…

IIS在Windows上的搭建

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 目录 一 概念: 二网络…

深入理解C++中的锁

目录 1.基本互斥锁(std::mutex) 2.递归互斥锁(std::recursive_mutex) 3.带超时机制的互斥锁(std::timed_mutex) 4.带超时机制的递归互斥锁(std::recursive_timed_mutex) 5.共享…

【python脚本】批量检测sql延时注入

文章目录 前言批量检测sql延时注入工作原理脚本演示 前言 SQL延时注入是一种在Web应用程序中利用SQL注入漏洞的技术,当传统的基于错误信息或数据回显的注入方法不可行时,例如当Web应用进行了安全配置,不显示任何错误信息或敏感数据时&#x…

【TS】TypeScript 原始数据类型深度解析

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 TypeScript 原始数据类型深度解析一、引言二、基础原始数据类型2.1 boolean2.2 …

苍穹外卖--sky-take-out(四)10-12

苍穹外卖--sky-take-out(一) 苍穹外卖--sky-take-out(一)-CSDN博客​编辑https://blog.csdn.net/kussm_/article/details/138614737?spm1001.2014.3001.5501https://blog.csdn.net/kussm_/article/details/138614737?spm1001.2…

Unity动画系统(2)

6.1 动画系统基础2-3_哔哩哔哩_bilibili p316 模型添加Animator组件 动画控制器 AnimatorController AnimatorController 可以通过代码控制动画速度 建立动画间的联系 bool值的设定 trigger p318 trigger点击的时候触发,如喊叫,开枪及换子弹等&#x…

错误 [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试 python ping

报错提示:错误 [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试 用python做了一个批量ping脚本,在windows专业版上没问题,但是到了windows服务器就出现这个报错 解决方法:右键 管理员身份运行 这个脚本 …

sql拉链表

1、定义:维护历史状态以及最新数据的一种表 2、使用场景 1、有一些表的数据量很大,比如一张用户表,大约1亿条记录,50个字段,这种表 2.表中的部分字段会被update更新操作,如用户联系方式,产品的…

在 WebGPU 与 Vulkan 之间做出正确的选择(Making the Right Choice between WebGPU vs Vulkan)

在 WebGPU 与 Vulkan 之间做出正确的选择(Making the Right Choice between WebGPU vs Vulkan) WebGPU 和 Vulkan 之间的主要区别WebGPU 是什么?它适合谁使用?Vulkan 是什么?它适合谁使用?WebGPU 和 Vulkan…

修改CentOS7 yum源

修改CentOS默认yum源为阿里镜像源 备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载ailiyun的yum源配置文件 CentOS7 yum源如下: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun…

[OC]萝卜圈Python手动机器人脚本

这是给机器人设置的端口,对照用 代码 # #作者:溥哥’ ##机器人驱动主程序 #请在main中编写您自己的机器人驱动代码 import msvcrt def main():a"none"while True:key_input msvcrt.getch()akey_inputif abw:print(a)robot_drv.set_motors(1,40,2,40,3,…