JVM提供的监控命令:btrace。

应用场景

线上出问题,无法增加日志、无法线上调试,需要实现切面功能

Java应用服务在生产环境中可能会出现各种各样的问题,有些问题在找到根本原因之前看似“不可思议”,有时并没有产生异常或者错误消息,这时我们无法根据已有的日志来定位问题,那么我们需要更多的信息如参数、返回值、程序逻辑判断、循环次数等来追踪问题。如果临时增加日志,则需要重新上线,成本较高,使用远程调试又会影响线上流量导致客户程序超时,这时btrace应运而生。btrace可以动态的跟踪Java运行时程序,将定制化的跟踪字节码切面注入运行类中,对运行代码无侵入,对性能的影响也可忽略不计。

使用方法

btrace [-p port] [-cp classpath] pid btrace-script

参数解析

  • port:指定btrace agent的服务端监听端口号,供客户端连接。
  • classpath:用于指定依赖的类加载路径。
  • pid:表示进程号,可通过jps或者ps命令获取。
  • btrace-script:btrace跟踪切面脚本。

在运行命令之前,我们需要编写btrace的跟踪脚本:

import java.util.Date;
import com.sun.btrace.BTraceUtils;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class Btrace {

	@OnMethod(class="com.cloudate.controller.AdminController",
			method="sayHello",
			location=@Location(Kind.RETURN))
	
	public static void sayHello() { // 单位是ns,要转为ms
		println(strcat("duration(ms):", str(duration/1000000)));
	}
}

这个跟踪脚本对业务代码的方法进行了拦截,并打印方法的执行时间:

public class AdminController {
	public String sayHello(String name, int age) {
		return "hello everyone";
	}
}

使用示例

btrace -p 2020 -cp ~/servlet-api.jar 1507 ~/BTrace.java

AdminController类的sayHello被调用时,控制台就会打印方法的执行时间,这对定位线上的棘手问题有非常大的帮助。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/87619357