开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
前言
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
生产环境使用
在生产环境遇到各种需要解决的jvm问题时,之前都是依赖jdk自带的jstat,jstack,jmap等来进行查询堆,栈,dump等,再进行仔细分析,查找具体问题点。虽然基本可以满足要求,但是界面显示不友好,且遇到一些奇特问题时,往往不能快速定位问题,非常麻烦。
Arthas
结合我的使用场景,解决了一部分生产环境遇到的问题。
启动
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
启动非常简单,直接jar包启动即可
jad 判断类是否有更新
遇到过打包后,始终没有走自己新的修改的代码,无法确定是打包的问题导致没有更新上去还是其他的原因导致的代码没有执行。以前的处理方式是把jar包下载下来再反编译看一下代码是不是最新的。 现在我们可以直接使用jad命令,直接显示运行中的最新class反编译代码
jad com.whpe.card.web.common.serverListen.StartupConfig
会打印出该类的加载classloader,类的路径,类的jad反编译代码。
解决
查询到class类确实没有更新,直接进行替换。arthas 也支持在线直接替换。方便快捷
dashboard 解决线程CPU占用过高,定位问题
可以很直观的看到线程的CPU占用,可以非常快速的定位到哪一个线程占用较多的cpu ,进行基本的排查定位。
我之前都是通过jstat -gcutil pid 2000来看内存的变化和使用情况,但是有一个缺点,不能知道老年代,survivor区域的大小,只能看到百分比和动态的变化。现在结合dashboard可以知道每个代的大小,使用比例。
thread
之前用netty的时候,有某种情况下会重复创建线程,且没有使用线程池,导致隔一段时间服务就假死了,看日志和服务器都没看出来什么问题,虽然通过jstack也可以看到这个原因,当时没有往这方面去想,后面通过thread查看后知道程序启动了很多相同的任务线程。
快速定位后,进行了处理,修复了bug 功能:
- 线程死锁
- 线程耗时堆栈,可以进行相应的优化,主要是IO
- 线程整体情况,数量,运行情况
profiler
为了应对大流量,大并发的请求,我们对核心的收单程序进行了性能优化,采用profiler来监控cpu耗时的火焰图。后续进行分析,找到耗时点并进行优化。 采用abtest进行的压测。
ab -n 10000 -c 100 -p heartbeat.txt -T text/plain http://10.10.209.95:8000/v1/posControl/interface_2/posHeartBeat
后续启动profiler profiler start
等待压测结束后,停止profilerprofiler stop --format html 输出成html格式进行查看
横轴越长,代表链路上统计耗时越长。纵轴越长代表调用链路越深。
后续我优化了redis请求,进行lua脚本合并。获取通用数据进行缓存处理等优化方式。都是依据火焰图进行分析,制定的优化方案。非常好用。
arthas还有非常多好用的命令,后续生产环境中也会逐步尝试。
其他一些比较实用的命令如下
| 命令 | 功能 |
|---|---|
| heapdump | 导出heap文件,用MAT工具进行分析 |
| jvm | 主要分析线程的统计情况,死锁线程,内存占用详情等 |
| classLoader | 直接加载类 |
| mc | 通过指定classloader来编译类 |
| retransform | 手动加载修改好的class文件 流程 jad -> mc -> retransform |
| stack | 方法调用栈 |
| trace | 统计方法耗时,后面会结合火焰图分析方法的耗时 |
| tt | 解决方法没有打印日志的情况,记录入参和返回信息,杀手级命令 |
后续我也会在docker项目中,默认都配置上arthas,替换到原始的jdk自带命令。直接快速定位并解决问题。