小伙伴们好,欢迎关注,一起学习,无限进步
文章目录
- Window 安装
- Linux 安装
- SpringBoot 整合 arthas
- 其他使用场景
Arthas是阿里巴巴开源的一款Java诊断工具,可以用于线上诊断问题、监控应用性能等。支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的
Tab
自动补全功能,本文将介绍Arthas的安装、常用命令以及一个简单的使用示例。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
官方文档:https://arthas.aliyun.com/
Window 安装
GitHub下载安装:https://github.com/alibaba/arthas/releases
下载 arthas-bin.zip 压缩包,或者使用命令下载 arthas-boot.jar
包
curl -O https://arthas.aliyun.com/arthas-boot.jar
在 windows
指定文件夹在解压,进入 arthas-boot.jar
文件所在的目录下,使用 cmd
控制面板打开,运行 java -jar arthas-boot.jar
命令,出现以下内容,选择对象项目运行进程的编号【4】
D:\environment\arthas-bin>java -jar arthas-boot.jar
[INFO] JAVA_HOME: D:\tools\Java\jdk1.8.0_291\jre
[INFO] arthas-boot version: 3.7.2
[INFO] Process 16964 already using port 3658
[INFO] Process 16964 already using port 8563
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 16964 org.jetbrains.jps.cmdline.Launcher
[2]: 33188 org.jetbrains.idea.maven.server.RemoteMavenServer36
[3]: 24952 org.jetbrains.idea.maven.server.RemoteMavenServer36
[4]: 11548 com.ruoyi.RuoYiApplication
[5]: 11788 org.jetbrains.idea.maven.server.RemoteMavenServer36
[6]: 12380 org.jetbrains.idea.maven.server.RemoteMavenServer36
[7]: 14972 org.jetbrains.jps.cmdline.Launcher
[8]: 2892 org.jetbrains.idea.maven.server.RemoteMavenServer36
[9]: 9324
常用命令列表可参考官方文档:命令列表
以下使用 trace 命令
- trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时
输入编号 4
运行成功截图
打开 IDEA
安装 arthas
插件,重启 IDEA
进入业务逻辑在方法名上右键,复制要执行追踪方法调用的命令
把以下命令粘贴到要执行 arthas
控制面板上,可以清楚的看到当前方法执行的事件,第几行代码花费的事件,
[arthas@20136]$ trace com.ruoyi.framework.web.service.SysLoginService login -n 5 --skipJDKMethod false
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 272 ms, listenerId: 1
`---ts=2024-03-08 15:50:33;thread_name=http-nio-8080-exec-2;id=76;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@24e00a46
`---[474.7417ms] com.ruoyi.framework.web.service.SysLoginService:login()
+---[2.61% 12.4108ms ] com.ruoyi.system.service.ISysConfigService:selectCaptchaEnabled() #70
+---[5.12% 24.2993ms ] com.ruoyi.framework.web.service.SysLoginService:validateCaptcha() #74
+---[0.00% 0.0143ms ] org.springframework.security.authentication.UsernamePasswordAuthenticationToken:<init>() #80
+---[0.00% 0.009ms ] com.ruoyi.framework.security.context.AuthenticationContextHolder:setContext() #81
+---[73.01% 346.6275ms ] org.springframework.security.authentication.AuthenticationManager:authenticate() #83
+---[0.00% 0.0183ms ] com.ruoyi.framework.security.context.AuthenticationContextHolder:clearContext() #100
+---[0.00% 0.0111ms ] com.ruoyi.framework.manager.AsyncManager:me() #102
+---[0.01% 0.0652ms ] com.ruoyi.common.utils.MessageUtils:message() #102
+---[0.03% 0.1608ms ] com.ruoyi.framework.manager.factory.AsyncFactory:recordLogininfor() #102
+---[0.10% 0.4626ms ] com.ruoyi.framework.manager.AsyncManager:execute() #102
+---[0.01% 0.0275ms ] org.springframework.security.core.Authentication:getPrincipal() #103
+---[0.00% 0.0127ms ] com.ruoyi.common.core.domain.model.LoginUser:getUserId() #104
+---[6.09% 28.9135ms ] com.ruoyi.framework.web.service.SysLoginService:recordLoginInfo() #104
+---[0.00% 0.0114ms ] java.lang.StringBuilder:<init>() #108
+---[0.01% min=0.013ms,max=0.0156ms,total=0.0286ms,count=2] java.lang.StringBuilder:append() #108
+---[0.00% 0.0115ms ] com.ruoyi.common.core.domain.model.LoginUser:getUser() #108
+---[0.00% 0.0119ms ] com.ruoyi.common.core.domain.entity.SysUser:getUserId() #108
+---[0.00% 0.0095ms ] java.lang.StringBuilder:toString() #108
+---[2.48% 11.75ms ] com.ruoyi.common.core.redis.RedisCache:getCacheObject() #109
+---[0.00% 0.0101ms ] com.ruoyi.common.utils.StringUtils:isNotEmpty() #110
+---[2.57% 12.2048ms ] com.ruoyi.common.core.redis.RedisCache:deleteObject() #112
+---[2.52% 11.9701ms ] com.ruoyi.common.core.redis.RedisCache:deleteObject() #113
`---[5.29% 25.1361ms ] com.ruoyi.framework.web.service.TokenService:createToken() #117
当前命令说明:
trace com.ruoyi.framework.web.service.SysLoginService login -n 5 --skipJDKMethod false
trace
:表示要追踪方法调用。com.ruoyi.framework.web.service.SysLoginService login
:表示要追踪的类和方法,这里是追踪com.ruoyi.framework.web.service.SysLoginService
类中的login
方法。-n 5
:表示只追踪前5次方法调用。--skipJDKMethod false
:表示不跳过JDK方法,即追踪JDK方法的调用。
Linux 安装
同理安装
下载
wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.7.2/arthas-bin.zip
直接下载会比较慢,可以接下载 arthas-boot.jar
包
wget https://arthas.aliyun.com/arthas-boot.jar
运行 java -jar arthas-boot.jar
,和 window 上控制面板执行命令一样
SpringBoot 整合 arthas
SpringBoot 整合 arthas-spring-boot-starter
,添加以下依赖
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.7.2</version>
</dependency>
application.yml
添加配置文件
arthas:
# telnetPort、httpPort为 -1 ,则不listen telnet端口,为 0 ,则随机telnet端口
# 如果是防止一个机器上启动多个 arthas端口冲突。可以配置为随机端口,或者配置为 -1,并且通过tunnel server来使用arthas。
# 通过http默认访问的端口
http-port: 8563
# 通过telnet默认访问的端口
telnet-port: 3658
session-timeout: 1800
# 127.0.0.1只能本地访问,0.0.0.0则可网络访问,但是存在安全问题
ip: 127.0.0.1
appName: arthas_test
# 默认情况下,会生成随机ID,如果 arthas agent配置了 appName,则生成的agentId会带上appName的前缀。
agent-id: abcdefghijklmnopqrstuvwxyz
# tunnel-server地址
tunnel-server: ws://127.0.0.1:7777/ws
启动项目
访问:http://ip:8563/
,出现以下页面则说明成功,根据 arthas
使用命令执行即可
其他使用场景
Arthas 的使用非常灵活,有时候甚至还会有一些意想不到的功能,除了上面这些使用场景,Arthas 的 Issues 中还收集了一些 用户案例,其中有几个案例对我印象很深,非常有启发性,可供参考。
使用 stack 命令定位 System.exit/System.gc 的调用来源:https://github.com/alibaba/arthas/issues/20
使用 sc 和 jad 排查 NoSuchMethodError 问题:https://github.com/alibaba/arthas/issues/160
使用 redefine 修改 StringBuilder.toString() 定位未知的日志来源:https://github.com/alibaba/arthas/issues/263
使用 trace javax.servlet.Servlet/Filter 排查 Spring Boot 应用 404/401 问题:https://github.com/alibaba/arthas/issues/429
使用 tt 定位 Java 应用 CPU 负载过高问题:https://github.com/alibaba/arthas/issues/1202
使用 profiler 做复杂链路分析,排查性能问题:https://github.com/alibaba/arthas/issues/1416
使用 trace 命令将接口性能优化十倍:https://github.com/alibaba/arthas/issues/1892