Java诊断工具Arthas——部署及演示

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

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

注: 以上内容来自官网

1 安装

下载命令

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

安装命令

java -jar arthas-boot.jar
//使用阿里云镜像下载arthas
java -jar arthas-boot.jar --repo-mirror aliyun --use-http

在安装之前需要启动一个java应用程序,否则会报下面的异常

[root@master arthas]# java -jar arthas-boot.jar --repo-mirror aliyun --use-http
[INFO] arthas-boot version: 3.4.5
[INFO] Can not find java process. Try to pass <pid> in command line.
Please select an available pid.

在安装的过程中需要指定被监控的Java应用程序
Java诊断工具Arthas——部署及演示_第1张图片

2 集成SpringBoot

上面的方式比较麻烦,还需要手动安装arthas并attach应用程序。arthas提供了Spring Boot Starter,可以在应用启动后自动启动arthas,并attach当前应用的进程,只需要配置一下依赖包即可。
maven依赖:

<dependency>
    <groupId>com.taobao.arthas</groupId>
    <artifactId>arthas-spring-boot-starter</artifactId>
    <version>3.4.5</version>
</dependency>

可以在application.properties中配置arthas需要的属性,例如:

arthas.appName=demo
//默认情况下,agentId会自动生成一个随机ID,如果配置了appName,agentId就是appName_随机Id
arthas.agentId=demo_123

3 Arthas Tunnel

一般开发人员没有线上机器的操作权限,而且现在都是分布式部署,一个服务会部署到多台机器上,操作起来也比较麻烦。因此,arthas提供了tunnel,可以远程操控多个agent。tunnel采用的WebSocket实现的,可以在浏览器里操作远程agent。
tunnel是一个SpringBoot应用,直接把jar包下载下来启动即可。
下载地址: arthas-tunnel-server
Java诊断工具Arthas——部署及演示_第2张图片
启动命令:

java -jar arthas-tunnel-server-3.4.6-fatjar.jar

web端的访问端口默认是8080,agent的连接端口默认是7777
在应用程序的application.properties中配置tunnel的服务地址

arthas.tunnelServer=ws://172.0.0.1:7777/ws

在浏览器中访问http://IP:8080/
在这里插入图片描述
在AgentId框里输入应用程序里配置的arthas.agentId=demo_123,点击Connect
Java诊断工具Arthas——部署及演示_第3张图片
http://IP:8080/actuator/arthas该路径可以查看到连接信息,用户名是arthas,密码在tunnel的启动日志里可以找到
Java诊断工具Arthas——部署及演示_第4张图片

4 实战

arthas命令大全
jvm相关指标信息参见另一篇文章:JVM内存监控及故障分析
定义一个类:TestController

@RestController
public class TestController {

    /**
     * 内存泄漏
     */
    @GetMapping("/memoryLeak")
    public void memoryLeak() {
        while (true) {
            this.list();
        }
    }

    static class MemoryLeakObject {
        byte[] o = new byte[10 * 1024 * 1024];
    }
    static List<MemoryLeakObject> list = new ArrayList<>();

    private void list() {
        list.add(new MemoryLeakObject());
    }

    /**
     * 死循环
     */
    @GetMapping("/endlessLoop")
    public void endlessLoop() {
        Thread thread = new Thread(() -> {
            while (true);
        }, "endlessLoop");
        thread.start();
    }
    
    /**
     * 方法链路追踪
     */
    @GetMapping("/trace")
    public void trace() throws InterruptedException {
        this.trace1();
    }

    private void trace1() throws InterruptedException {
        System.out.println("======");
        TimeUnit.SECONDS.sleep(2);
        this.trace2();
    }

    private void trace2() throws InterruptedException {
        System.out.println("******");
        TimeUnit.SECONDS.sleep(3);
    }
}

dashboard: 查看实时监控数据面板
Java诊断工具Arthas——部署及演示_第5张图片
如果执行了memoryLeak方法,可以很明显的看到内存的变化情况,此时内存已被撑满。
thread [ID]: 查看某个线程的栈信息
在这里插入图片描述
jad [类全路径]: 反编译类
Java诊断工具Arthas——部署及演示_第6张图片
thread -n [n]: 查看前n个最繁忙的线程
Java诊断工具Arthas——部署及演示_第7张图片
trace [class-pattern] [method-pattern]: 查看方法调用链路,能够查看每个方法的执行时间,但是每次只能查看一级调用,如下图
Java诊断工具Arthas——部署及演示_第8张图片
注意trace使用的是字节码增强技术,也就是给指定的方法插入了切面,因此诊断完时要执行stop命令,或对类执行reset命令

reset TestController

你可能感兴趣的:(监控,arthas,诊断)