天天看点

BTrace工具(linux版)---线上调试神器

     如果在分析线上问题时,发现日志打的不全,无法定位怎么办?添加日志重新上线,不是一个好方法,特别是调试时,可能要反复添加日志来定位问题或者线上出现的问题很难再复现,根本就没有机会添加日志再继续分析,这时就可以使用btrace。

    btrace是jvm实时监控的工具,是性能调优和线上问题诊断的神器,btrace基于动态字节码修改技术,来实现对运行时的java程序进行跟踪和替换。也就是说可以在不重启jvm的情况下监控系统运行情况,获取jvm运行时的数据信息,比如方法参数、返回值、全局变量、堆栈信息等。

首先可以对方法进行定位拦截,获取方法的入参、返回值、执行时间等信息。

第二可以查看某类对象的创建情况。

第三可以对内存使用情况进行统计,可以查看对象大小。

第四可以查看同步块执行情况。

注意问题:

1.不恰当的使用btrace可能导致jvm崩溃

2.btrace做的修改会一直生效的,直到重启jvm后,才会消除

3.可以通过设置jvm参数取消btrace的安全限制

下面版本是linux版本,实际场景中应该先在window桌面版(https://blog.csdn.net/wwd0501/article/details/94482419)中调试后,再部署到线上环境中。官方声明,不恰当的使用BTrace可能导致JVM崩溃,如在BTrace脚本使用错误的class文件,所以在上生产环境之前,务必在本地充分的验证脚本的正确性。

一、 安装JDK

BTrace工具(linux版)---线上调试神器
JAVA_HOME=/usr/java/jdk1.8.0_111
export JAVA_HOME
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
           

二、 安装BTrace 

1)下载地址:https://github.com/btraceio/btrace/releases/tag/v1.3.11.3     (btrace-bin-1.3.11.3.tgz或btrace-bin-1.3.11.3.zip)

2)解压缩 

BTrace工具(linux版)---线上调试神器
tar -zxvf btrace-bin-1.3.11.3.tgz 
           
BTrace工具(linux版)---线上调试神器

3)设置环境变量至当前用户目录下的.profile 

添加如下配置:

BTRACE_HOME=/data/soft/btrace
export BTRACE_HOME
export PATH=$PATH:$BTRACE_HOME/bin
           

执行source .profile

三、 示例代码

public class Calculator {
    private int c = 1;

    public int add(int a, int b) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return a + b;
    }
}
           
import java.util.Random;

public class BTraceDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        Random random = new Random();
        while (true) {
            System.out.println(calculator.add(random.nextInt(10), random.nextInt(10)));
        }
    }
}
           
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class BTraceTest {

    @OnMethod(
            clazz = "Calculator",
            method = "add",
            location = @Location(Kind.RETURN)
    )
    public static void trace1(int a, int b, @Return int sum) {
        println("trace1:a=" + a + ",b=" + b + ",sum=" + sum);
    }
}
           

注意:若是有包路径,clazz要写全路径,比如:clazz="com.test.Calculator"

1、执行javac BTraceDemo.java

2、执行java BTraceDemo

3、查看BTraceDemo进程号

BTrace工具(linux版)---线上调试神器

4、执行btrace 1792 BTraceTest.java 

1792是BTraceDemo的进程ID 

trace1方法实现对Calculator类的add方法的入参和返回值进行追踪,结果如下。 

BTrace工具(linux版)---线上调试神器

若是出现btrace报错:Port 2020 unavailable

原因是btrace会在remote JVM(pid:122810)agent开启一个远程socketserver,默认端口是2020,正好我这台服务器有多个JVM实例,当我在第一个JVM上执行之后,第一个就会报错。正确的做法是:btrace -p 2021 1972 T.java 。

在实际项目中,直接就是监控我们的项目进程ID

package com.test.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.test.Calculator;

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

	@RequestMapping("/demo")
	public String demo(int a , int b) {
		Calculator cal = new Calculator();
		return cal.add(a, b) + "";
	}
}
           
package com.test;

public class Calculator {
	private int c = 1;

    public int add(int a, int b) {
        c++;
        return a + b;
    }
}
           
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

/* 此为btrace程序*/
@BTrace
public class TracingScript {
	/* put your code here */
    @OnMethod(
        clazz = "com.test.Calculator",
        method = "add",
        location = @Location(Kind.RETURN)
    )
    public static void func(int a,int b,@Return int result,@Duration long time){
        println("调用堆栈:");
        jstack();
        println(strcat("方法参数A:",str(a)));
        println(strcat("方法参数B:",str(b)));
        println("cost time : " + time);
        println(strcat("方法结果:",str(result)));    
        println();
    }
}
           

先启动项目,例如上面的两个类在wareic项目中

BTrace工具(linux版)---线上调试神器

然后再执行btrace 21362 TracingScript.java

(btrace -v 21362 TracingScript.java 类似dedug模式,打印的信息更详细。)

此时访问http://localhost:8080/test/demo?a=1&b=2,就可以看到追踪信息。

windows桌面版:https://blog.csdn.net/wwd0501/article/details/94482419,可以先在本地多测试几遍,然后再上线。