前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Arthas】实战教程

【Arthas】实战教程

原创
作者头像
后端码匠
修改2023-11-06 10:06:51
5330
修改2023-11-06 10:06:51
举报
文章被收录于专栏:后端码匠

【Arthas】实战教程

前言

最近团队在研究线上问题排查方式,发现线上存在CPU飙升问题,测试环境无法复现,查阅资料发现 Arthas 能够分析此类问题。

排查利器

Arthas,开源的Java诊断工具。

功能

那么Arthas能帮我们做什么事情呢?详细的用法大家可以查官方文档,这里带大家实践。

代码语言:shell
复制
可以监控到JVM的实时的运行状态;
可以实时查看系统的运行状况;
遇到线上高流量系统,没有打日志,同时不能debug,线下却又不能重现,可以无须重启在线查看类方法输入输出,如同日志一般;
怀疑代码没有commit就发布了,它帮你在线查看;
......

安装启动

这里推荐快速简单的安装方法,大家也可下载包安装。

代码语言:shell
复制
curl -O https://arthas.aliyun.com/arthas-boot.jar --下载jar包
java -jar arthas-boot.jar  --启动
java -jar arthas-boot.jar -h  --查看帮助

正常上面操作就已经能够监听Java进程,但是我的项目用的Docker部署需要把 arthas 整合到镜像内,Dockerfile 文件如下

代码语言:shell
复制
...

# copy arthas
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas

...

如果你用的是JRE那么用的时候,肯定会有 tool.jar找不见的异常。

所以在打镜像的时候需要选择jdk,具体可以看官方文档。

代码语言:shell
复制
https://arthas.aliyun.com/doc/docker.html

我所做的项目用了自己的基础镜像,暂时无法在打镜像的时候引入JDK,这就需要特殊处理下,步骤如下:

1、在Linx本地JDK目录如下

代码语言:shell
复制
[root@master jdk1.8.0_221]# pwd
/home/jdk1.8.0_221

2、找到运行的容器

代码语言:shell
复制
[root@master jdk1.8.0_221]# docker ps | grep hms
fcf3c7aed879        hub.codingce.com/codingce-dev/codingce-hms                       "/bin/sh -c 'java -X…"   About an hour ago   Up About an hour                                                  k8s_codingce-health_codingce-health-87f8bdf66-6lxd9_default_225daeaa-abd4-4591-a827-36ad6b36f50f_8
6270d035c617        hub.codingce.com/codingce-dev/codingce-hms-web                   "/docker-entrypoint.…"   2 days ago          Up 2 days                                                         k8s_health2-web_health2-web-7ddbb7cdd5-xxwbn_sci-edas_da7d65c9-9c54-4445-8ecb-678bee853ab2_0
[root@master jdk1.8.0_221]# 

本地JDK复制到容器中

代码语言:shell
复制
docker cp jdk1.8.0_221/ de37f7e97560:/opt/java

然后就可以进入容器启动Arthas。

代码语言:shell
复制
[root@master jdk1.8.0_221]# docker exec -it fcf3c7aed879 bash
root@codingce-87f8bdf66-6lxd9:/# 
root@codingce-87f8bdf66-6lxd9:/opt# ls
arthas	java
root@codingce-87f8bdf66-6lxd9:/opt# cd arthas/
root@codingce-87f8bdf66-6lxd9:/opt/arthas# ls
arthas-agent.jar  arthas-boot.jar  arthas-client.jar  arthas-core.jar  arthas-spy.jar  arthas.properties  as-service.bat  as.bat  as.sh  async-profiler  install-local.sh  lib	logback.xml  math-game.jar
root@codingce-87f8bdf66-6lxd9:/opt/arthas# 

运行Arthas。

代码语言:shell
复制
root@codingce-87f8bdf66-6lxd9:/opt/arthas# /opt/java/jre/bin/java -jar arthas-boot.jar
[INFO] JAVA_HOME: /opt/java/jre
[INFO] arthas-boot version: 3.7.1
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 6 hms.jar

星号代表选中的进程。

代码语言:shell
复制
[INFO] arthas home: /opt/arthas
[INFO] The target process already listen port 3658, skip attach.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.                           
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'                          
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.                          
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |                         
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'                          

wiki       https://arthas.aliyun.com/doc                                        
tutorials  https://arthas.aliyun.com/doc/arthas-tutorials.html                  
version    3.7.1                                                                
main_class                                                                      
pid        6                                                                    
time       2023-11-05 15:57:09                                                  

[arthas@6]$ 

系统dashboard

可以查看系统的整体情况如下图:线程、内存、系统运行时信息等

JVM全景报表

帮助你分析现有系统情况,类加载情况,线程情况,系统内存情况等等如下图:并未截取全部。

thread 命令

代码语言:shell
复制
thread 查看当前线程
thread id 查看指定线程id 的堆栈
thread -n 2 查看cpu最忙的前2个线程
thread -b, 找出当前阻塞其他线程的线程
thread -n 2 -i 1000 列出1000ms内最忙的2个线程堆栈

thread -b,找出当前阻塞其他线程的线程。

有时候发现服务卡住了, 一般情况是:

某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成阻塞。这个命令可以解决。

watch命令,执行数据监测

线上没有打日志,同时不能debug,线下却又不能重现,watch命令可以无须重启在线查看类方法输入输出,如同日志一般。

能观察到的方法监测的数据范围:返回值、抛出异常、入参。

代码语言:shell
复制
watch demo.MathGame primeFactors "{params,returnObj}" -x 4 
观察 demo.MathGame.primeFactors 的入参 和 返回值 遍历深度4

[arthas@6]$ watch com.codingce.health.service.impl.HealthAssessmentReportServiceImpl pageVo "{params,returnObj}" -x 4

jad命令,反编译指定已加载类的源码

你有时候有这样的疑惑,现在运行的代码是我提交的代码吗?虽然master有,但是线上运行的包是这个master打的吗?它可以直接在线反编译。

代码语言:shell
复制
jad demo.MathGame  反编译demo.MathGame
jad --source-only demo.MathGame 反编译demo.MathGame只展示源码
jad demo.MathGame main 反编译demo.MathGame main函数
jad demo.MathGame --classLoaderClass sun.misc.Launcher$AppClassLoader 指定classloader,用于多个classloader加载的情况

trace命令

跟踪方法内部调用路径,并输出方法路径上的每个节点上耗时。

代码语言:shell
复制
trace demo.MathGame run 追踪demo.MathGame run 方法
trace demo.MathGame run -n 1  追踪demo.MathGame run 方法只1次即退出
trace demo.MathGame run '#cost > 10' 追踪大于10ms的
代码语言:shell
复制
[arthas@6]$ trace cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl pageVo
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 2) cost in 500 ms, listenerId: 2
`---ts=2023-11-05 17:37:44;thread_name=XNIO-1 task-4;id=6c;is_daemon=false;priority=5;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@345f69f3
    `---[54.506314ms] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl$$EnhancerBySpringCGLIB$$ef541:pageVo()
        `---[99.69% 54.339228ms ] org.springframework.cglib.proxy.MethodInterceptor:intercept()
            `---[79.59% 43.248517ms ] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl:pageVo()
                `---[98.15% 42.448222ms ] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl:pageCommon() #781

`---ts=2023-11-05 17:37:49;thread_name=XNIO-1 task-26;id=8a;is_daemon=false;priority=5;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@345f69f3
    `---[24.51515ms] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl$$EnhancerBySpringCGLIB$$ef541:pageVo()
        `---[99.81% 24.46882ms ] org.springframework.cglib.proxy.MethodInterceptor:intercept()
            `---[72.11% 17.643921ms ] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl:pageVo()
                `---[99.86% 17.619807ms ] cn.com.codingce.service.impl.HealthAssessmentReportServiceImpl:pageCommon() #781

sc 命令

查看JVM已加载的类信息。

代码语言:shell
复制
sc demo.*  模糊搜索demo包下所有类
sc -d demo.MathGame 打印demo.MathGame的详细信息

火焰图生成

代码语言:shell
复制
profiler start 启动采集(默认是CPU)
profiler getSamples 查看采样的数量
profiler status  查看采样的状态(是否在运行,运行了多久)
profiler stop 停止并生成火焰图

x轴代表采样总量(也就是此刻所有执行的耗时cpu的方法)。

这是注意的是x 轴并不代表时间,而是所有的调用方法合并后,按字母顺序排列。

Y轴代表方法的调用栈深度,每一层都是一个方法。顶部是正在执行的方法。当然调用栈越深,火焰就越高。

鼠标可以点击的选中的每个框就代表了一个栈里的函数,其宽度可以直接理解为CPU时间占比(其实是采样的数量以及与采样总量的占比)。

那么,也就是说占比比较宽的框就表示:

  • 该函数运行时间较长(单次时间长)
  • 被调用次数较多.(调用频率高) 进而被采样的次数比较多,占用的CPU时间多。

另外火焰图

绿色部分代表Java代码;

黄色部分代表JVM C++代码;

橙色部分代表内核态C语言代码;

红色代表用户态C语言代码;

由此可知,火焰图可以直观的帮我们分析CPU占用情况。

我用的Docker需要把容器里面的html文件复制到Linux

代码语言:shell
复制
docker cp fcf3c7aed879:/arthas-output/20231105-161622.html /home/arthas

Linux文件传输到本地

nc命令

服务端

代码语言:shell
复制
nc -l 10078 < 20231105-161622.html

本地

代码语言:shell
复制
nc 10.100.28.108 10077 > 20231105-161622.html

官方文档

Github: https://github.com/alibaba/arthas

文档:https://arthas.aliyun.com/doc/

总结

Arthas功能庞大,是线上排查问题,性能分析的利器,建议大家使用。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【Arthas】实战教程
    • 前言
      • 排查利器
        • 功能
          • 安装启动
            • 系统dashboard
              • thread 命令
                • watch命令,执行数据监测
                  • jad命令,反编译指定已加载类的源码
                    • trace命令
                      • sc 命令
                        • 火焰图生成
                          • 官方文档
                            • 总结
                            相关产品与服务
                            容器服务
                            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档