网站首页 > java教程 正文
简介
Arthas 是Alibaba开源的Java诊断工具,动态跟踪Java代码;实时监控JVM状态,可以在不中断程序执行的情况下轻松完成JVM相关问题排查工作 。支持JDK 6+,支持Linux/Mac/Windows。这个工具真的很好用,而且入门超简单,十分推荐
使用场景
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?接下来,围绕这6个问题,学习下Arthas的基本用法。
安装
执行下面命令下载
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
然后等待下载,当进入下面的页面说明下载成功了:
监测排查命令
监测排查命令是 Arthas 中最常用的命令。
请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 stop 或将增强过的类执行 reset 命令。
monitor
方法执行监控。可对方法的调用次数,成功次数,失败次数等维度进行统计。
# -b:计算条件表达式过滤统计结果(方法执行完毕之前),默认是方法执行之后过滤
# -c:统计周期,默认值为 120 秒
# params[0] <= 2:过滤条件,方法第一个参数小于等于2
monitor -b -c 5 com.test.testes.MathGame primeFactors "params[0] <= 2"
stack
输出当前方法被调用的调用路径。
很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。
# -n:执行次数
stack demo.MathGame primeFactors -n 2
thread
查看当前线程信息,查看线程的堆栈。
# 没有参数时,默认按照 CPU 增量时间降序排列,只显示第一页数据
# -i 1000: 统计最近 1000ms 内的线程 CPU 时间
# -n 3: 展示当前最忙的前 N 个线程并打印堆栈
# --state WAITING:查看指定状态的线程
thread
# 显示指定线程的运行堆栈
thread id
# 找出当前阻塞其他线程的线程,注意,目前只支持找出 synchronized 关键字阻塞住的线程, 如果是 java.util.concurrent.Lock 目前还不支持。
thread -b
输出:
- Internal 表示为 JVM 内部线程,参考 dashboard 命令的介绍。
- cpuUsage 为采样间隔时间内线程的 CPU 使用率,与 dashboard 命令的数据一致。
- deltaTime 为采样间隔时间内线程的增量 CPU 时间,小于 1ms 时被取整显示为 0ms。
- time 为线程运行总 CPU 时间。
trace
方法内部调用路径,并输出方法路径上的每个节点上耗时。
trace 命令在定位性能问题的时候特别有用。
# -n 1:限制匹配次数
# --skipJDKMethod false:默认情况下,trace 不会包含 jdk 里的函数调用,如果希望 trace jdk 里的函数,需要显式设置
# --exclude-class-pattern :排除掉指定的类
trace javax.servlet.Filter * -n 1 --skipJDKMethod false --exclude-class-pattern com.demo.TestFilter
# 正则表达式匹配路径上的多个类和函数,达到多层 trace 的效果
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
动态 tradce参考:https://arthas.aliyun.com/doc/trace.html#动态-trace
tt
方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。
说明:
- tt 命令的实现是:把函数的入参/返回值等,保存到一个Map<Integer, TimeFragment>里,默认的大小是 100。
- tt 相关功能在使用完之后,需要手动释放内存,否则长时间可能导致 OOM。退出 arthas 不会自动清除 tt 的缓存 map。
- 需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。
# -l:显示tt记录
tt -l
# -s:检索tt记录,比如:-s 'method.name=="primeFactors"'
tt -s 'method.name=="primeFactors"'
# -t:这个参数的表明希望记录下类 *Test 的 print 方法的每次执行情况。
tt -t
# 查看具体调用信息
tt -i 1003
# -w:--watch-express 观察时空隧道使用 ognl 表达式
tt -w '@demo.MathGame@random.nextInt(100)'
# 重做一次调用,当我们对程序做出了修改之后,希望再次调用观测结果,此时你需要 -p 参数
# --replay-times:指定调用次数
# --replay-interval:指定多次调用间隔(单位 ms, 默认 1000ms)
tt -i 1004 -p
# 通过索引删除指定的 tt 记录
tt -d 1001
# 清除所有的 tt 记录
tt --delete-all
Spring MVC里获取对于的 bean:
# 获取Spring Context里的bean
tt -n 1 -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
watch
函数执行数据观测,通过编写 OGNL 表达式进行对应变量的查看。
- watch 命令定义了 4 个观察事件点,即 -b 函数调用前,-e 函数异常后,-s 函数返回后,-f 函数结束后。
- 4 个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出。
- 这里要注意函数入参和函数出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表函数入参外,其余事件都代表函数出参。
- 当使用 -b 时,由于观察事件点是在函数调用前,此时返回值或异常均不存在。
- 在 watch 命令的结果里,会打印出location信息。location有三种可能值:AtEnter,AtExit,AtExceptionExit。对应函数入口,函数正常 return,函数抛出异常。
# -x表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是 1。
# -x最大值是 4,防止展开结果占用太多内存。用户可以在ognl表达式里指定更具体的 field。
watch demo.MathGame primeFactors -x 3
# 可以使用ognl表达式进行条件过滤
watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0" "#cost>200"
# 可以使用 target.field_name 访问当前对象的某个属性
watch demo.MathGame primeFactors 'target.illegalArgumentCount'
# watch 构造函数
watch demo.MathGame <init> '{params,returnObj,throwExp}' -v
# watch内部类
watch OuterClass$InnerClass
总结
arthas确实降低我们排查java问题的难度,但arthas的命令那么多,很多时候我们都记不住,就算能记,我也不会去记,我正常使用的套路是先help 命令,然后找到相应的示例,最后照猫画虎。
- 上一篇: 操作系统学习福利:600 条最强 Linux 命令总结
- 下一篇: java中的调优命令
猜你喜欢
- 2024-12-07 Java Java命令学习系列(一)——Jps
- 2024-12-07 MySQL技术数据库基础操作命令大全,建议收藏
- 2024-12-07 Java中命令行调用大坑
- 2024-12-07 可怕!CPU竟然暗藏了这么多未公开的指令
- 2024-12-07 Telnet命令是什么?如何使用?
- 2024-12-07 java命令行参数
- 2024-12-07 Java的jar启动命令
- 2024-12-07 telnet命令的用法
- 2024-12-07 Java 的隐秘超能力:用 ProcessBuilder 指挥操作系统的任意命令
- 2024-12-07 java中的调优命令
你 发表评论:
欢迎- 06-04C++优先级调度队列(Priority Queue)
- 06-04数据结构与算法-优先队列(优先队列 数组实现)
- 06-04什么是优先队列?(优先队列原理)
- 06-04终于有架构大牛把分布式系统概念讲明白了,竟然用了足足800页
- 06-04分布式事物如何保证接口请求顺序性?
- 06-04微服务下分布式事务模式的详细对比
- 06-04彻底掌握分布式事务2PC、3PC模型(分布式事务 三阶段)
- 06-04分布式事务最全详解(看这篇就够了)
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)