简介

我们在开发中有时候会碰到以下些问题,那么这款阿里开源的工具将可以帮助你一一解决。Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?
  8. 怎样直接从JVM内查找某个类的实例?

下载

如果你要使用docker或者k8s安装此工具,参考:https://arthas.aliyun.com/doc/docker.html

  1. curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar

基本使用

启动你需要诊断的项目,比如我这里是我的springboot项目。然后启动这个诊断程序java -jar arthas-boot.jar,选择你要诊断的程序进程,诊断工具便启动了。详细案例参考官方文档
image.png

使用问题

1. well-known file is not secure

image.png
原因分析:这边应该是客户方直接内嵌了arthas,后面我在平台云上使用暂未发现

命令列表

dashboard

image.png

thread

查找出线程运行情况 thread,找出消耗cpu前十的线程thread -n 5的线程堆栈信息,或者直接指定某个线程thread id,thread-b:查看是否有死锁
image.pngimage.png

jvm

可以看出年轻代用的收集器是paralle scavenge收集器+老年代的Parallel Old

ParallelScavenge(PS)的young collector就如其名字所示,是并行的拷贝式收集器。本来这个young collector就是“Parallel Scavenge”所指,但因为它不兼容原本的分代式GC框架,为了凸显出它是不同的,所以它的young collector带上了PS前缀,全名变成PS Scavenge。对应的,它的old collector的名字也带上了PS前缀,叫做PS MarkSweep。

image.png

jad

可以反编译我们的类,就相当于可以查看线上代码是否是最新代码,主要是利用了类加载器重新加载的特性
image.png

redefine

可以修改线上代码,不用重新部署。你可以在本地将编译好的代码class文件,远程上传比如上传到/tmp/a.class,然后在readfine /tmp/a.class。这样就不用停服务器了

headdump

此命令可以下载我们的dump文件,类似我们的jmap命令 jmap -dump:format=b,file=heapDump.phrof pid

Trace

可以查找某个方法的调用链,比如A服务调用了B服务,B服务调用了C,这样就可以定位出各个方法所消耗的时间。伪代码如下,命令:trace com.dongnaoedu.network.humm.jvm.controller.TestDemoController test1对test1进行监听,然后通过curl xxx:port/test/test 分别调用1次。就会输出test1方法对应下的方法占用的时间
image.png

package com.dongnaoedu.network.humm.jvm.controller;

@RestController
@RequestMapping("/test")
public class TestDemoController {

    @GetMapping("/test")
    public String test() throws InterruptedException {
        String str = "hello word";
        for (int i = 0; i < 5; i++) {
            System.out.println(str);
            test1();
        }
        return str;
    }

    public void test1() throws InterruptedException {
        Thread.sleep(1000L);
        System.out.println("test1 sleep 1s");
        test2();
    }

    public void test2() throws InterruptedException {
        Thread.sleep(1000L);
        System.out.println("test2 sleep 1s");
    }
}

当然你也可以对test进行监听,会输出test方法对应test1方法占用的时间和次数,就容易定位出问题
image.png

参考:https://arthas.aliyun.com/doc/commands.html,详细语法参考官方文档



参考:https://github.com/alibaba/arthas/blob/master/README_CN.md