介绍 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。 Arthas能为我们解决哪些问题 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! 是否有一个全局视角来查看系统的运行状况? 有什么办法可以监控到JVM的实时运行状态? 与SkyWalking的区别 Skywalking是一个可观测性分析平台(Observability Analysis Platform,OAP)和一个应用性能管理(Application Performance Management,APM)系统。 Quick Start 启动本地Java进程 (实例工程,空SpringBoot项目) 下载arthas-boot curl -O https://arthas.aliyun.com/arthas-boot.jar,此步骤仅完成基础包下载,大小为139K上下 执行命令 java -jar arthas-boot.jar,选择需要attch的Java进程,进入arthas的命令界面 基本操作(官网入门示例) dashboard 执行dashboard,将展示当前进程的信息。如图: 通过此命令可以查看JVM的堆内存情况,以及活跃线程、JVM基本信息等内容。 jad反编译代码 通过jad指令,反编译class watch方法执行数据观测(查看函数入参和返回值) 通过模拟对入参 *2 的程序,反应watch的强大。 通过watch命令,监听方法的一切行为。watch的参数比较多,以下摘抄自官网: class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观察表达式 condition-express 条件表达式 [b] 在方法调用之前观察 [e] 在方法异常之后观察 [s] 在方法返回之后观察 [f] 在方法结束之后(正常返回和异常返回)观察 [E] 开启正则表达式匹配,默认为通配符匹配 [x:] 指定输出结果的属性遍历深度,默认为 1 monitor方法执行监控(什么时候执行了) 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 condition-express 条件表达式 [E] 开启正则表达式匹配,默认为通配符匹配 [c:] 统计周期,默认值为120秒 [b] 在方法调用之前计算condition-express monitor -c 5 top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController index 每5秒监听一次,统计耗时、失败率、总次数、成功次数、失败次数等信息 通过表达式过滤不需要的请求方法调用。 trace方法内部调用路径,输出方法路径上的节点耗时(我调用了谁) trace top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController index 因为代价比较高(这属于skywarking的工作范围),trace默认只支持一层的耗时分析。但官网提供了多层trace的方法,具体见:https://arthas.aliyun.com/doc/trace.html stack方法输出当前方法被调用的调用路径(谁调用了我) stack top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController getResult -n 3 tt 记录方法请求的信息,方便重做请求和查看结果 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测 watch指令复杂,通过tt记录请求的信息后面可以针对性分析 2. 进阶操作 热加载代码 首先声明:在生产环境热更新代码是不很不好的行为。 但是肯定有它使用的场景。 涉及到几个命令: jad(反编译指定已加载类的源码) sc(查看JVM已加载的类信息) mc(内存编译器,内存编译.java文件为.class文件)、 redefine(加载外部的.class文件,redefine到JVM里) jad反编译代码,vim调整代码逻辑 jad --source-only top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController > /tmp/IndexController.java 通过 sc 命令,找到类加载器 sc -d *IndexController 通过 mc 内存编译java -> class mc -c 31221be2 /tmp/IndexController.java -d /tmp 通过 redefine 热加载 redefine /tmp/top/imyzt/learning/arthas/arthaswebdemo/web/controller/IndexController.class 全流程 profiler🔥图 通过 profiler start/stop 获得一份程序的火焰图 火焰图查看工具 JDK JMC:https://github.com/openjdk/jmc JProfiler(付费): https://www.ej-technologies.com/download/jprofiler/files 如何读懂火焰图? 如何读懂火焰图? - 阮一峰的网络日志 使用arthas+jprofiler做复杂链路分析 · Issue #1416 · alibaba/arthas 进阶使用&命令列表 https://arthas.aliyun.com/doc/advanced-use.html https://arthas.aliyun.com/doc/commands.html 常用使用场景分析和讨论 同传统方式进行对比,最大的目的是为了解决目前低效的生产环境问题排查方式。 通过watch观察方法入参,是否可以客户反馈使用出了问题,但是又不知道小程序发过来的请求具体是啥? 通过stack观察,某个方法什么时候被调用了,被谁调用了? 通过tt记录请求信息,便于重做请求,模拟用户操作? 通过后台异步任务,观察定时周期出现问题的代码,阿里描述:当线上出现偶发的问题,比如需要watch某个条件,而这个条件一天可能才会出现一次时,异步后台任务就派上用场了,详情请参考这里 以上描述的操作虽然能解决很多问题,但是是否面临着一个更大的问题? 适合生产环境的实践 Web_Console 在attrch成功之后,直接访问本地3658端口,可以通过web界面操作。 默认情况下,arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用 --target-ip参数指定listen的IP。 Tunnel Server 下载arthas-tunnel-server,本地java -jar启动,Web界面监听8080端口,WebSocket通信监听7777端口。 java -jar arthas-boot.jar --tunnel-server 'ws://127.0.0.1:7777/ws' 可以通过http://127.0.0.1:8080/actuator/arthas访问本地,获得已连接到tunnel-server的arthas-client。密码在启动控制台。 通过上面的操作,虽然免去了去生产环境机器直接操作arthas这种不现实的问题,但是在Web界面操作还有一个问题,就是谁给我们绑定执行 java -jar arthas-boot.jar --tunnel-server 'ws://127.0.0.1:7777/ws' 这个命令呢....... 与SpringBoot集成,更适合生产环境的实践 增加Maven依赖 <dependency> <groupId>com.taobao.arthas</groupId> <artifactId>arthas-spring-boot-starter</artifactId> <version>3.5.2</version> </dependency> 调整配置文件 server.port=8892 spring.application.name=arthas-demo # 建议不指定, 会根据 spring.application.name 生成 #arthas.agent-id=arthas-demo arthas.tunnel-server=ws://localhost:7777/ws # -1会随机分配端口 arthas.http-port=-1 arthas.telnet-port=-1 查看agentId tunnel-server连接后操作 对性能的影响 通过spring-boot-starter的方式,在应用启动时,就对进程自动完成了attach,对于性能方面的影响是不大的,下面有两个官方的回复,从原理是解释了这个问题。 开发团队回复: 目前arthas-spring-boot-starter方式是长期启动状态,对程序的性能有什么影响吗? · Issue #1843 · alibaba/arthas 是否进行过性能评估,attach之后对原进程性能有多大的影响呢 · Issue #44 · alibaba/arthas 如何记住各种命令 https://arthas.aliyun.com/doc/idea-plugin.html 遇到的一些坑 Pid=1无法Attach linux保护机制,jstack无法attach住pid<=5的进程,arthas也无法使用,通用解决方案是使用tini挂载java进程。 https://github.com/alibaba/arthas/issues/362 Arthas端口问题 应用被Arthas-Boot attch之后,包括应用本身的端口,同时还会监听另外两个端口: 默认情况下,Arthas的Telnet端口是3658,HTTP端口是8563,这个常常让用户迷惑。在新版本里,在3658端口同时支持Telnet/HTTP协议。 在浏览器里访问 http://localhost:3658/ 也可以访问到Web Console了。 在后续的版本里,考虑默认只侦听 3658端口,减少用户的配置项。 当启动tunnel-server后,8080与7777端口也被监听。 与Skywalking的兼容性问题 java.lang.ClassFormatError: null、skywalking arthas 兼容使用 当出现这个错误日志java.lang.ClassFormatError: null,通常情况下都是被其他字节码工具修改过与arthas修改字节码不兼容。 比如: 使用 skywalking V8.1.0 以下版本 无法trace、watch 被skywalking agent 增强过的类, V8.1.0 以上版本可以兼容使用,更多参考skywalking配置 skywalking compatible with other javaagent bytecode processing。 JVM版本问题 启动Arthas的Java版本和启动应用的Java版本要保持一致 推荐文章 Arthas源码学习-1_慢一拍的coder-CSDN博客 Arthas Tutorials 工商银行打造在线诊断平台的探索与实践 Arthas使用到的技术 Arthas运行原理 tt命令探究 执行 tt -t top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController index 下载正在运行的字节码文件 dump top.imyzt.learning.arthas.arthaswebdemo.web.controller.IndexController 查看字节码 javap -c -s -v -l xxx.class 相关文章:Arthas原理系列(四):字节码插装让一切变得有可能
Read More ~