我在组内的Java问题排查分享
前言
最近翻看以前写的 PPT, 发现了在2019年做的一次技术分享,关于 Java 问题排查,由于没什么公司机密可言,整理下分享给大家~
线上问题处理流程
直接放PPT截图吧,现在看来依然不过时

问题排查
可从三个方面入手
- 知识:有些问题,思考一下就有答案,就像传说中多隆那样,回忆下就知道第83行代码有问题~
- 工具:当然不是每个人都能做到过目不忘,也有可能这代码完全不是你写的,这时就需要靠工具来定位问题
- 数据:程序运行时产生的数据,也能提供很多线索
知识
知识有很多方面,这里简单列举一下:
- 语言(本文特指 Java):如 JVM 知识、多线程知识等
- 框架:如 Dubbo、Spring 等
- 组件:如 Mysql、RocketMq 等
- 其他:如网络、操作系统等
举个例子,我们需要理解 Java 对象从申请到被回收整个过程,这个图非常清晰,建议烂熟于心:

然后也要了解常见的垃圾收集器:

吞吐量=单位时间内处理的请求数量=运行代码时间 / (运行代码时间 + 垃圾回收时间)
以 ParNew + CMS 为例 ,尝试回答如下几个问题:
- 为什么要分代收集?— 关键字:效率
- 对象什么时候进入老年代?— 关键字:年龄、大小
- Young GC 与 Full GC 什么时候发生?— 关键字:Eden 不足、Old 不足、Meta 不足、map/System.gc
如果我们了解上述的这些知识后,举个实际例子,当我们发现 Young GC 频繁触发,耗时高,该如何优化?
首先思考,Young GC 什么时候触发?答案是 Eden 区不足。
接着,Young GC 耗时主要是哪里耗时?答案是扫描 + 复制,扫描通常很快,复制比较慢。
那我们对症下药,增加新生代大小试试,结果真的解决问题了,为什么?我们也分析一下
新生代大小为 M 时,假设对象存活 750ms,young GC间隔 500ms,扫描时间为 T1,复制时间为 T2
- 新生代大小为 M 时:频率 2次/s,每次耗时 T1 + T2
- 新生代扩大为 2M 时:频率 1次/s,每次耗时 2T1
由于T2远远大于T1,所以2T1 < T1 + T2
这就是知识的力量~
工具
Java 栈中的工具,也分为这几类:
- JDK 自带:如 jstat、jstack、jmap、jconsole、jvisualvm
- 第三方:MAT(eclipse插件)、GCHisto、GCeasy(在线GC日志分析工具,https://gceasy.io/)
- 开源:大名鼎鼎的Arthas、bistoury(去哪网开源)、Async-profiler
这些工具的原理,我们也需要稍微了解下,比如 Cpu profiler大概有两类:
- 基于采样:优点是性能开销低,缺点是采样有频率限制,存在SafePoint Bias问题
- 插桩:所有方法添加 AOP 逻辑,优点是精准采集,缺点是性能开销高
比如 uber 开源的 uber-common/jvm-profiler,它就是基于采样的 Cpu profiler,缺点就是存在 SafePoint Bias 问题,比如有一次排查一个 Cpu 占用问题,就采集到了这样的火焰图,可以看到几乎没啥用
SafePoint(安全点) 可以简单理解为 JVM 可以停顿下来的特定位置的点,如果采样的位置是特定的点,那么采样就不具有代表性,因为可能在非 SafePoint 时可能消耗了更多的 Cpu,这种现象就被称为 SafePoint Bias 问题。

但我用另一个 jvm-profiling-tools/async-profiler 来采集,就能看到性能瓶颈:

虽然 Async-profiler 也是基于采样做,但它能避免 SafePoint Bias 问题,原因是它采用了 AsyncGetCallTrace 的黑科技。于是依据 Async-profiler 给出的火焰图进行优化,Qps 从 58k 涨到 81k,Cpu 反而从72%下降到了41%

数据
数据包括:
- 监控数据,如APM、metric、JVM监控、分布式链路追踪等等数据
- 程序运行数据:如业务数据、AccessLog、GC log、系统日志等
这部分就按实际来分析,没有统一模板可言。
经验
说了这么多,从经验角度总结了如下常见问题该从哪些方面入手:
- 执行异常:查看日志、debug、请求重放
- 应用僵死:jstack
- 耗时高:trace跟踪、Benchmark
- Cpu利用率高:Cpu profile分析
- GC频繁、耗时高:GC log分析
- OOM、内存占用高、泄漏:dump内存分析
案例分享
Cobar僵死,进程端口在,但不能处理请求
先踢掉故障机器,保留现场再排查问题,根据日志,定位为内存泄漏

小思考:能通过日志直接确定是哪里内存泄露吗?— 答案:不能
具体定位可dump内存下载到本地分析,文件如果太大,可以先压缩下
jmap -dump:format=b,file=/cobar.bin ${pid}
使用 eclipse 的插件 MAT 分析,过程就不放了,结果是发现了一个我们对 Cobar 自定义修改导致的 Bug,如果对内存分析感兴趣,可以直接看我这几篇实战文章:
网关耗时高
使用 Arthas trace 跟踪调用
trace com.beibei.airborne.embed.extension.PojoUtils generalize

接入 Sentinel 导致应用僵死
接入限流降级利器 Sentinel 后,配置一条规则,触发后导致应用僵死,可使用 jstack 进行排查,一眼就看出问题所在
jstack ${pid} > jstack.txt

最后
本文最早分享于2019年12月,刚好过去2年,由于是 PPT 整理而来,行文没有那么丝滑,但问题排查的思路、手段依然是这些,大家学废了吗?
搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。
我在组内的Java问题排查分享的更多相关文章
- java 多线程 线程组ThreadGroup;多线程的异常处理。interrupt批量停止组内线程;线程组异常处理
1,线程组定义: 线程组存在的意义,首要原因是安全.java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的.但如果在不同的线程组中,那么就不能"跨线程组&q ...
- 模拟QQ分组(具有伸缩功能) (添加开源框架的光闪烁效果)SimpleExpandableListAdapter 适配器的用法,并且可添加组及其组内数据。
package com.lixu.qqfenzu; import java.util.ArrayList; import java.util.HashMap; import java.util.Lis ...
- [SQL]用于提取组内最新数据,左连接,内连接,not exist三种方案中,到底谁最快?
本作代码下载:https://files.cnblogs.com/files/xiandedanteng/LeftInnerNotExist20191222.rar 人们总是喜欢给出或是得到一个简单明 ...
- java问题排查总结
前些天发现:http://hellojava.info/这个站点,关于java问题排查分析总结线上故障总结其实是最有价值的,好的总结就是一个系统演进历史,是团队难得的积累沉淀. 花了不少时间看了下,顺 ...
- ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法,先分组,然后在组内排名,分组计算,主表与附表一对多取唯一等
ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法 今天在使用多字段去重时,由于某些字段有多种可能性,只需根据部分字段进行去重,在网上看到了row ...
- 组内Linq培训记录
注: 由于该培训是在组内分享,先写成了Word,而word中的代码都以截图方式呈现了,而在博客园不能很方便的粘贴截图进来,所以我用插入代码的方式加进来,如果文中说“如下图”或“如下图代码”,那么就直接 ...
- sql 分组后 组内排名
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN) 简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW ...
- sql查询技巧,按时间分段进行分组,每半小时一组统计组内记录数量
今天拿到一个查询需求,需要统计某一天各个时间段内的记录数量. 具体是统计某天9:00至22:00时间段,每半小时内订单的数量,最后形成的数据形式如下: 时间段 订单数 9:00~9: ...
- 如何用SQL实现组内前几名的输出
关于问题 如何查询组内最大的,最小的,大家或许都知道,无非是min.max的函数使用.可是如何在MySQL中查找组内最好的前两个,或者前三个? 什么是相关子查询 在提出对于这个问题的对应方法之前,首先 ...
随机推荐
- CSS引入字体文件
在css引入字体文件可以直接把以下代码复制到css文件中 /* 字体声明 */ @font-face {font-family: 'icomoon';src: url('fonts/icomoon.e ...
- 【数据结构与算法Python版学习笔记】递归(Recursion)——定义及应用:分形树、谢尔宾斯基三角、汉诺塔、迷宫
定义 递归是一种解决问题的方法,它把一个问题分解为越来越小的子问题,直到问题的规模小到可以被很简单直接解决. 通常为了达到分解问题的效果,递归过程中要引入一个调用自身的函数. 举例 数列求和 def ...
- LCP 07.传递消息
题目 小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下: 有 n 名玩家,所有玩家编号分别为 0 - n-1,其中小朋友 A 的编号为 0 每个玩家都有固定的若干个可传信息的其他玩家(也可 ...
- [no code][scrum meeting] Alpha 3
项目 内容 会议时间 2020-04-07 会议主题 技术规格说明书review 会议时长 1h30min 参会人员 产品经理+后端技术组长(伦泽标)+OCR竞品调研成员(叶开辉)+架构文档负责(黎正 ...
- BUAA软件工程个人博客作业
软件工程个人博客作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业 我在这个课程的目标 团队完成好的软件,并对自己作出规划 这个作 ...
- Intellij IDEA 2021.2.3 最新版免费激活教程(可激活至 2099 年,亲测有效)
申明,本教程 Intellij IDEA 最新版破解.激活码均收集与网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除.如条件允许,建议大家购买正版. 本教程更新于:2021 年 10 月 ...
- 用Python画如此漂亮的专业插图 ?简直So easy!
本文整理自知乎问答,仅用于学术分享,著作权归作者所有.如有侵权,请联系我删文处理.多多转发,多多学习! 方法一 强烈推荐 Python 的绘图模块 matplotlib: python plottin ...
- netty系列之:netty实现http2中的流控制
目录 简介 http2中的流控制 netty对http2流控制的封装 Http2FlowController Http2LocalFlowController Http2RemoteFlowContr ...
- Python中根据时间自动创建文件夹
导语 电脑桌面文件太多查找起来比较花费时间,并且凌乱的电脑桌面也会影响工作心情,于是利用python根据时间自动建立当日文件夹,这样就可以把桌面上文件按时间进行存放. 代码实现 # _*_codi ...
- 基于Dapr的 Azure 容器应用
微软在 Ignite 2021 大会上发布了预览版的Azure Container Apps,这是一个完全托管的无服务器容器运行时间,用于大规模构建和运行现代应用程序.从2021 年 11 月 2 日 ...