zoukankan      html  css  js  c++  java
  • Java BTrace实战(1)--BTrace的入门和使用

    前言:
      对线上的java服务, 往往采用日志进行问题处理和分析. 倘若日志缺乏相关的信息时, 那又该如何处理? 远程调试会影响服务的正常工作, 修改代码重新部署的方案其实时性和灵活性难以保证(线上服务的流程繁琐, 问题追踪的不确定性), 有没有两全的完美方案(不影响正常服务, 又灵活/无侵入性)呢?
      答案是有, 它就是人见人爱, 花见花开的神器BTrace. 那BTrace究竟是这么样的神器, 为何它只要998(啊呸..., -_-bbb). 好了, 让我们一步一步的掀起它的红盖头来. 本系列讲述BTrace的使用/原理/技巧, 希望对大家有所帮助, 对自己也是种学习经历.
      本文着重讲解Btrace的安装, 原理和初步使用.

    BTrace的原理篇:
      BTrace的首字母B来自于bytecode, 某种程度上透露了其原理. 其能在不影响目标程序运行的前提下, 通过HotSpot虚拟机的HotSwap技术动态插入原本不存在的调试代码, 其是基于了JDK 6的Instumentation来实现的. 具体的原理介绍, 可以参考博文: Btrace的基本原理

    BTrace的安装:
      BTrace的安装有两种方式.
      1). VisualVM的插件形式存在
      VisualVM的BTrace插件安装, 通过其插件管理器来简单安装.

      评注: 具体在VisualVM中: 工具->插件->可用插件, 选择BTrace WorkBench安装
      2). 单独的BTrace命令行工具
      BTrace下载网址: https://kenai.com/projects/btrace/downloads/directory/releases
      btrace-bin的目录结构如下:
      
      评注: bin为二进制/脚本目录, docs是api文档, samples包含btrace的各种例子和说明 

    BTrace的使用:
      让我们来构造一个简单的java程序, 来作为测试程序.

    public class Calculator {
    
      public int add(int a, int b) {
        return a + b;
      }
    
      public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Calculator roboot = new Calculator();
        while ( scanner.hasNext() ) {
          int a = scanner.nextInt();
          int b = scanner.nextInt();
          int c = roboot.add(a, b);
          System.out.println(
            String.format("%d + %d = %d", a, b, c));
        }
      }
    
    }	

      评注: Calculator类的函数add用于a+b的计算, Scanner用于交互, 从命令行读入输入参数.
      接着我们编写一段BTrace代码, 用于跟踪Calculator类的add函数.

    import com.sun.btrace.annotations.*;
    import static com.sun.btrace.BTraceUtils.*;
    
    @BTrace
    public class TracingScript {
        @OnMethod(
            clazz="mmxf.btrace.test.Calculator", 
            method="add", 
            location=@Location(Kind.RETURN)
        )
        
        public static void func(
                int a, int b, 
                @Return int result) {
            println("trace: =======================");
            jstack();
            println(strcat("a:", str(a)));
            println(strcat("b:", str(b)));
            println(strcat("result:", str(result)));
        }
    }

      先借助VisualVM的BTrace插件来完成调试:
      可从VisualVM获取java的进程, 然后点击Trace Application, 导入BTrace Script, 点击运行即可.
      结果如图所示:
      
      当然我们也可以借助btrace的命令行工具来实现:
      1). 确定java进程的pid
      可借助jps -l来实现
      
      评注: 选取pid为7547的进程id为目标进程
      2). 执行btrace命令
      btrace <pid> <btrace_script>
      
      评注:打印出了堆栈信息, 以及add方法的输入参数以及函数返回结果 

    总结:
      本文只是个开头, 对btrace的安装和使用有个初步的认识, 后续的文章会对btrace的概念, 用途和实战例子进行讲述. 敬请期待.

  • 相关阅读:
    ThinkPHP实现定时任务
    VUE 父子组件之间通信传值 props和 $emit,事件触发传值ref,以及兄弟组件之间的通信传值 eventBus
    JS链接转换为二维码
    VUE 动态切换列表active样式
    微信内置浏览器video标签自动全屏的问题
    JS监听video视频播放时间
    JS数据统计表 highcharts.js的运用
    JS 自动返回每个月的天数
    JS 一键复制插件应用 和 原生实现
    JS enter键一键登录
  • 原文地址:https://www.cnblogs.com/mumuxinfei/p/3944823.html
Copyright © 2011-2022 走看看