【Java】使用jstack、jstat、jmap线上问题排查一例

2024-01-15 10:18

本文主要是介绍【Java】使用jstack、jstat、jmap线上问题排查一例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

现象

前阵子线上发布了一些功能,主要是针对客户群做的社群网络,大数据这边针对用户的通讯录、通话记录、设备等信息,计算其对应的社群网络,然后根据社群对应的指标来判断用户的风险情况。当然新老用户的逻辑有所区分,这里就不再深入阐述了。功能上线后,出现了一个比较诡异的事情:系统CPU和内存都飙升,几乎都快把主机撑爆了。

定位最消耗资源的线程

因为发布是在凌晨,使用app的用户还是比较少的,经过沟通,我们建议运维暂时先不下线新功能。给我们几分钟时间定位问题。这时候我们首先想到要查看是哪个线程最消耗资源。(以下示例为事后线下复现,非当时线上真实资源消耗情况)

  • 查看java进程

ps -ef | grep kafka-1.0 | grep -v grep

93ec254723f7b96fb6e182b1faed8e88.png

  • 查看进程中最消耗资源的线程

在我们查看到进程号以后,可以通过top命令查看对应进程中的线程,以及cpu使用情况

top -Hp 100728

a80fd509765fa38b2e2d81aee627165f.jpeg

  • 转换为十六进制

printf "%x\n" 130870

12f87e7c20bb9e03c2931c1873d16a4b.png

可见线程号为:1ff36

接下来我们就需要用到jstack来查看

jstack 100728 > 100728.jstack

这样我们就把线上应用的堆栈信息给dump下来了,接下来我们可以看看jstack导出的文件主要有哪些内容,以及线程号为:1ff36的线程当时正在进行什么操作。截止目前我们使用的上面的示例实际并不是当时线上的截图,而是后续为了说明当时的场景做的。当时jstack导出的文件我们保留下来了,对应的最占用CPU资源的前几个线程为GC线程。我们有理由认为是内存被撑爆导致的频繁GC,进而导致CPU居高不下。 查看GC情况

/usr/local/jdk1.8.0_11/bin/jstat -gcutil 100728 1000 100

我们发现FGC特别频繁,几秒钟就会进行一次,因为full gc会导致stop the world所以这必然是有问题的,而S0,S1几乎为0,eden区和old区都占满了,即使进行了FGC依然无法回收,由此我们怀疑是在程序运行中产生了大对象无法回收导致频繁FGC: 

df72de034fd9875ac2c7f8a02f8f1475.png

使用IBM的dump文件分析工具

我们先看下jstack下来的文件内容:

c1e380acbe230686f06bfc9967870534.jpeg

推荐大家一个工具:IBM Thread and Monitor Dump Analyzer for Java(点击下载),真的是线程dump文件的分析利器,看起来非常直观。

使用该工具打开dump文件

934b7537240517c8003cf9576b07c704.jpeg

我们发现其中有大量的Waiting on condition等待,它们都是调用的sun.misc.Unsafe.park(Native Method)方法,再看看Thread Details都是hbase连接在获取数据

641699fed700c753357035c81aff2959.jpeg

这里很可能是因为获取了大量的数据导致的内存占用居高不下。但是目前也只能提供一个方向性的参考,并没有定位到具体的开发代码,我们看了这么多wait和调用的方法大多也都是定位到了开发框架的源码。我们可以通过搜索对应项目中的包,看看截止当时应用程序都执行了那些代码,如我们项目中所有的代码都是com.maiya开头的,很幸运目前用户流量还不大,并且调用的程序代码并不复杂,我们发现了一个可疑的地方:

1db57c39afb182f5054ca0aef8979545.jpeg

如上图所示,正是本次上线的代码,正在调用hbase的查询接口,那么是否就是hbase表的问题呢,难道如我们上面所猜想的,因为数据量过大导致的出现了大对象?我们count了下对应的表,发现表数据达到了惊人的2亿数据。而且一个用户下有多条重复数据,HBase中为什么会有重复数据呢?原来是因为key设计的问题,导致本该覆盖的记录,并没有覆盖,而是新增了。在数据重复统计多次以后,数据量猛增。最终导致了上面的问题。

至此已经定位出来原因了,程序并不需要进行修改,只要对HBase表进行重构,数据入库逻辑修改即可。数据修正后,程序重启后也正常了。 实际上我们也可以通过jmap查看程序中的class对象占用内存情况。不过dump出来的文件一般都比较大,大家要慎重。

使用java自带的jvisualvm,可以分析heap.hprof文件中的内容:

ec541b9ac49719f7f8a8364bbf8e8184.jpeg

使用jstack只能复现当时线程的方法栈,是一个静态的场景,所以一般要多导出几次,分析对比,如果某个应用程序线程在多次的jstack文件中一直存在,那么可能就需要我们多加关注了。

这篇关于【Java】使用jstack、jstat、jmap线上问题排查一例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608554

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数