Java 诊断利器 Arthas使用

这篇具有很好参考价值的文章主要介绍了Java 诊断利器 Arthas使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述

Arthas是一款阿里巴巴开源的 Java 线上诊断工具,功能非常强大,可以解决很多线上不方便解决的问题。

Arthas诊断使用的是命令行交互模式,支持JDK6+,Linux、Mac、Windows 操作系统,命令还支持使用 tab 键对各种信息的自动补全,诊断起来非常利索。

官网:https://arthas.aliyun.com/

Arthas(阿尔萨斯)能为你做什么?
Arthas 是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。

当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到 JVM 的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
怎样直接从 JVM 内查找某个类的实例?
Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
 

二、下载安装

官方推荐使用 arthas-boot 进行安装,非常方便,以下是基于 Linux 系统环境进行演示,一般解决线上问题也是基于 Linux 环境。

第一步:下载

在任何目录下载 arthas-boot 这个包。

wget https://alibaba.github.io/arthas/arthas-boot.jar

第二步:启动

java -jar arthas-boot.jar --target-ip 0.0.0.0

 

默认情况下, arthas server 侦听的是 127.0.0.1 这个IP,如果希望远程可以访问,可以使用--target-ip 的参数

arthas-boot 是 Arthas 的启动程序,它启动后,会列出所有的 Java 进程,输入需要诊断的目标进程序号即可。

Arthas支持通过 Web Socket来连接。

当在本地启动时,可以访问 http://127.0.0.1:8563/ ,通过浏览器来使用 Arthas。

输入 help 可以看到常用的帮助命令:

arthas-boot.jar 支持很多参数,可以执行 java -jar arthas-boot.jar -h 查看

第三步:选择进程

运行 arthas-boot 后,控制台会显示所有 Java 进程,选择一个你需要诊断的进程。

如第二步所示,这里有只有一个 Java 进程,输入序号1,回车,Arthas会附到目标进程上,并输出日志:

[root@ofp-ofppricefeed-app-6ffbf6fc85-vz8qx arthas]# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.5.0
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 27 org.apache.catalina.startup.Bootstrap

 至此安装启动完成

三、使用

启动完成后,当前光标会进入 arthas 的控制台,接受各种操作命令。

dashboard

输入 dashboard 显示当前系统的实时数据面板,按 ctrl+c 即可退出。

java arthas,# 开发vlog,java,开发语言

数据说明:

  • ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
  • NAME: 线程名
  • GROUP: 线程组名
  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
  • STATE: 线程的状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME: 线程运行总时间,数据格式为分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是daemon线程

 

thread

查看当前 JVM 的线程堆栈信息。

  • **thread **查询全部线程
  • thread -n 5 打印前5个最忙的线程并打印堆栈
  • thread -all 显示所有匹配的线程
  • thread -n 3 -i 1000 列出1000ms内最忙的3个线程栈
  • thread –state WAITING 查看指定状态的线程,(TIMED_WAITI、WAITING、RUNNABLE等等)
  • thread -b 找出阻塞其他线程的线程,当出现死锁后,会提示你出现死锁的位置
     

sc

查看 JVM 已加载的类详细信息。

Search-Class 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,sc -d *MathGame

如果搜索的是接口,还会搜索所有的实现类。比如查看所有的 Filter 实现类:

sc javax.servlet.Filter

-d 参数可以打印出类加载的具体信息,方便定位类加载问题

sc 支持通配符,比如搜索所有的 StringUtils

sc *StringUtils

打印类的 Field 信息:

sc -d -f demo.MathGame

sm

查看已加载类的方法信息

Search-Method 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。

sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到

查看 String 类的全部方法:

sm java.lang.String

查看具体方法的信息:

sm java.lang.String toString

通过 -d 参数可以打印函数的具体属性,展示每个方法的详细信息():

sm -d java.math.RoundingMode

jad

反编译指定已加载类的源代码

jad demo.MatthGame

  • jad demo.MathGame 将内存加载的class反编成代码和classloader信息(注:不是源代码)
  • **jad --source-only demo.MathGame **将内存加载的class反编译成java代码

trace

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

package demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class MathGame {
    private static Random random = new Random();
    private int illegalArgumentCount = 0;
    
    public List<Integer> primeFactors(int number) {
        /*44*/         if (number < 2) {
            /*45*/             ++this.illegalArgumentCount;
            throw new IllegalArgumentException("number is: " + number + ", need >= 2");
        }
        ArrayList<Integer> result = new ArrayList<Integer>();
        /*50*/         int i = 2;
        /*51*/         while (i <= number) {
            /*52*/             if (number % i == 0) {
                /*53*/                 result.add(i);
                /*54*/                 number /= i;
                /*55*/                 i = 2;
                continue;
            }
            /*57*/             ++i;
        }
        /*61*/         return result;
    }
    
    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        while (true) {
            /*16*/             game.run();
            /*17*/             TimeUnit.SECONDS.sleep(1L);
        }
    }
    
    public void run() throws InterruptedException {
        try {
            /*23*/             int number = random.nextInt() / 10000;
            /*24*/             List<Integer> primeFactors = this.primeFactors(number);
            /*25*/             MathGame.print(number, primeFactors);
        }
        catch (Exception e) {
            /*28*/             System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
        }
    }
    
    public static void print(int number, List<Integer> primeFactors) {
        StringBuffer sb = new StringBuffer(number + "=");
        /*34*/         for (int factor : primeFactors) {
            /*35*/             sb.append(factor).append('*');
        }
        /*37*/         if (sb.charAt(sb.length() - 1) == '*') {
            /*38*/             sb.deleteCharAt(sb.length() - 1);
        }
        /*40*/         System.out.println(sb);
    }
}

  • trace demo.MathGame run (监控追踪MathGame类下面的run方法) 

java arthas,# 开发vlog,java,开发语言

 

  • trace demo.MathGame run -n 1 (监控追踪MathGame类下面的run方法,只监控一次)

java arthas,# 开发vlog,java,开发语言

  • trace --skipJDKMethod false demo.MathGame run -n 1 (监控run所有方法,因为trace默认不追踪jdk自带的方法–skipJDKMethod false 就是开启追踪jdk默认的方法)

 java arthas,# 开发vlog,java,开发语言

  • trace demo.MathGame run ‘#cost > 0.1’ (查询大于0.1ms的执行方法)

 java arthas,# 开发vlog,java,开发语言

 

stack

查询某个方法被执行的时候的调用路径

  • stack demo.MathGame primeFactors (查询primeFactors被调用的时候调用的引用顺序)

java arthas,# 开发vlog,java,开发语言

  • stack demo.MathGame primeFactors ‘params[0]<0’ -n 2(显示入参为0的引用路径,显示两次)

java arthas,# 开发vlog,java,开发语言

tt

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。于是乎,TimeTunnel 命令就诞生了。
 

  • 查询三次findUserById 方法的调用详情

**tt -t -n 3 com.example.demo.arthas.user.UserController findUserById **

java arthas,# 开发vlog,java,开发语言

  • 查看所有的tt记录

 tt -l

java arthas,# 开发vlog,java,开发语言

 

  • 查看tt列表的详情,比如入参和出参

tt -i 1001 (1001是INDEX的值)

java arthas,# 开发vlog,java,开发语言

 

monitor

对某个方法的调用进行定时监控。

monitor cn.javastack.springbootbestpractice.web.JsonTest getUserInfo -c 5

-c 5:表示每5秒统计一次,统计周期,默认值为120秒。

监控维度说明:

监控项 说明
timestamp 时间戳
class 类名
method 方法名
total 调用次数
success 成功次数
fail 失败次数
rt 平均响应时间
fail-rate 失败率

watch

watch 命令可以查看函数的:

  • 参数
  • 返回值
  • 异常信息

watch demo.MathGame primeFactors returnObj

watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2

  1. 第一个参数是类名,支持通配
  2. 第二个参数是函数名,支持通配
  3. 第三个参数是定义返回值
  4. -x 2 是为了将结果展开

返回值表达式实际是一个 ognl 表示,支持一些内置对象:

  • loader
  • clazz
  • method
  • target
  • params
  • returnObj
  • throwExp
  • isBefore
  • isThrow
  • isReturn

watch命令支持按请求耗时进行过滤:

watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'

Arthas在 watch/trace 等命令时,实际上是修改了应用的字节码,插入增强的代码。显式执行 reset 命令,可以清除掉这些增强代码

再如

watch cn.javastack.springbootbestpractice.web.JsonTest getUserInfo ‘{params, returnObj}’ -x 2 -b

java arthas,# 开发vlog,java,开发语言

 

以上监控的是一个方法的入参情况,在方法执行前监控:-b,遍历深度:-x 2。

vmoption查看/更新虚拟机参数

这个命令可以看到我们的java项目在运行时设置了哪些参数,命令没有参数时会打印所有的vm参数

java arthas,# 开发vlog,java,开发语言

  • vmoption 查询全部虚拟数据
  • vmoption PrintGCDetails 查看指定的vm参数
  • vmoption PrintGCDetails true 更新指定的vm参数

sysprop

命令可以查看当前JVM的系统属性(System Property)

java arthas,# 开发vlog,java,开发语言

 

  • sysprop 查询全部JVM系统属性
  • sysprop java.version 查询单个属性
  • sysprop user.country CN 修改单个属性

getstatic

通过getstatic命令可以方便的查看类的静态属性

 java arthas,# 开发vlog,java,开发语言

  • getstatic demo.MathGame random 格式为getstatic <类路径><静态属性名字>

mc

Memory Compiler/内存编译器,编译.java文件生成.class。

retransform

加载外部的.class文件,retransform jvm已加载的类

quit/exit

退出当前 Arthas。

这个命令仅退出当前连接的客户端,附到目标进程上的 Arthas 会继续运行,端口不会关闭,下次连接时可以直接连接使用。

shutdown

关闭 Arthas 服务端,退出所有 Arthas 客户端。

以上演示了 几个常用命令的基本使用,各种命令的使用详情可以在命令带 --help 进行查阅。

更多其他命令请参考:

https://alibaba.github.io/arthas/commands.html

四、实战案例

热更新代码(修改正在运行的java程序)

注:修改jvm内存的代码需要注意两个点,第一不能添加新的字段信息,第二添加的代码如果方法还在执行就不会生效

1、下载测试用例

# 下载测试用例
wget https://github.com/hengyunabc/spring-boot-inside/raw/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jar
# 运行用例
nohup java -jar demo-arthas-spring-boot.jar

2、把需要修改的类反编译出来

# 使用jad 将jvm的class文件反编译成.java文件保存到临时目录
jad --source-only com.example.demo.arthas.user.UserController > /fyx/tmp/UserController.java

3、退出arthas修改代码

# 退出arthas
stop
# 进入目录
cd /fyx/tmp 
# 修改代码
vim UserController
package com.example.demo.arthas.user;

import com.example.demo.arthas.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    
    @GetMapping(value={"/user/{id}"})
    public User findUserById(@PathVariable Integer id) {
        logger.info("id: {}", (Object)id);
        if (id != null && id < 1) {
            logger.info("返回的数值有问题{}",id);
            return new User(id.intValue(),"name"+id);
        }
        return new User(id.intValue(), "name" + id);
    }
}


4、查看UserController的类加载器的hashcode

#进入arthas查看UserController的hash码
[arthas@10181]$ sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash
classLoaderHash   5674cd4d

5、将修改的代码编译成字节码并添加类加载器

# -c <类加载器hashcode> <需要编译的路径> -d <字节码生成的路径>
mc -c 5674cd4d /fyx/tmp/UserController.java -d /fyx/tmp/

 6、加载更改的代码

retransform /fyx/tmp/com/example/demo/arthas/user/UserController.class

7、访问修改的代码

发现我们新添加的代码是有效的

java arthas,# 开发vlog,java,开发语言

 

如果arthas使用完后一定要使用stop命令推出程序,不然下次监听其他服务的时候就会监听不到。解决方案就是重新进上一次的监听的程序再执行一次stop命令。

总结下来,使用 Arthas 可以很方便的诊断一个 Java 应用程序,如:系统数据面板、JVM实时运行状态、类加载情况、监控方法执行情况、显示方法执行路径等。文章来源地址https://www.toymoban.com/news/detail-724065.html

到了这里,关于Java 诊断利器 Arthas使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM 诊断神器-Arthas实战

    阿里开源的Java诊断工具,它可以在运行时对Java应用程序进行动态诊断和调试 当你遇到以下类似问题而束手无策时, Arthas 可以帮助你解决 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? 遇到问

    2024年02月07日
    浏览(35)
  • 线上诊断神器-arthas基本应用

    什么是Arthas呢? ​Arthas 是一款阿里推出的 线上监控诊断产品 ,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题

    2023年04月20日
    浏览(31)
  • 记1次生产环境java进程内存泄漏问题定位(使用Arthas)

    简介 | arthas, Alibaba 开源的 Java 诊断工具,参照文档安装使用很简单,在线下载或者离线下载后解压运行,启动arthas-boot.jar,会自动扫描jps进程,根据序号选择后进入arthas界面: 常用的是dashboard,thread命令,dashboard命令能扫面当前java进程的全局信息,包括堆栈和线程信息,

    2024年02月22日
    浏览(56)
  • 阿里开源的java而分析工具(arthas)

    1、官网地址:https://alibaba.github.io/arthas/quick-start.html 2、安装 wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 发生这个问题的原因有两个: 一个是目前机器中没有安装Oracle的jdk; 一个是没有java程序运行 解决方案: 1.卸载openJDK  安装Oracle的jdk  参加地址:https://

    2024年02月04日
    浏览(38)
  • 利用Arthas+APM监控进行Java性能深度定位

    大家可能都用过APM监控,包括开源的Skywalking、商用的卓豪(ZOHO)ManageEngine APM应用性能监控、以及云监控产品如听云(Server监控),这些APM监控产品大大方便了我们实时监控应用性能,并实现性能深度透视监控。 但是这些监控手段离真正能够定位性能问题还是有一段距离,有

    2024年02月14日
    浏览(40)
  • java性能安全:OOM问题排查、Arthas分析高CPU问题、防止Dos攻击

    一、OOM问题 分析流程: 第一步:进程分析,分析老年代回收次数和消耗时间 第二步:日志分析,找出OOM发生时间的日志来锁定执行方法,对应的机器ip 第三步:找到对应的ip机器查看,进一步分析 第四步:下载的dump,使用mat分析堆内存,找到堆占用率前3,查看堆指向 问题

    2024年02月03日
    浏览(37)
  • Arthas使用教程(8大分类)

    1、简介 GitHub地址 码云地址 Arthas 是 Alibaba 开源的Java诊断工具,深受开发者喜爱。 当你遇到以下类似问题而束手无策时, Arthas 可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception ? 我改的代码为什么没有执行到?难道是我没 commit ?分支搞错了

    2024年02月03日
    浏览(46)
  • docker 容器内 使用 arthas

    确定使用的jdk 下载arthas工具 curl -O https://arthas.aliyun.com/arthas-boot.jar 复制到容器内的/opt/arthas 目录 查找java的进程ID 启动arthas 就可以启动成功了 如果有其他错误 (1 服务器使用openjdk 如果你系统上使用的jdk是openjdk,在运行java -jar xxx.jar时,会出现Can not find java process. Try to run

    2024年02月06日
    浏览(40)
  • 使用阿里巴巴开源神器Arthas进行性能分析

    目录 前言: Arthas介绍 启动 分析命令 Profiler工具 前言: Arthas是一款由阿里巴巴开源的Java诊断工具,它可以在生产环境中帮助开发人员快速地定位问题,并进行高效的性能分析。通过在命令行中输入简单的

    2024年02月11日
    浏览(93)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包