美文网首页读书笔记javatool
跟 grays-anatomy 比, 才知道自己写的东西有多幼稚

跟 grays-anatomy 比, 才知道自己写的东西有多幼稚

作者: haitaoyao | 来源:发表于2016-08-15 22:32 被阅读2214次

    通过比较作者2011年左右开发的一个简单的 Java Troubleshooting 工具 simple-profiler 与神器 greys-anatomy 的差距, 知差距而后勇

    那是2011年(或者是 2012 年?), 看到 @bluedavvy 大神推荐 BTrace,跟进学习了一下才发现的确是神器一枚。小试牛刀,解决了一个线上问题,但总感觉写 BTrace 脚本有些门槛,尝试在公司内部推广结果效果不好。本着不重写一遍神器就体会不到神器究竟有多牛的指导思想,撸起袖子写了一个简易版的工具:simple-profiler
    时隔接近4年, 偶然发现了神器 greys-anatomy,才知道自己的差距,决定写篇文章对比一下,整理一下思路。

    基础

    1. Java Attach API

    Java Attach API 是一个提供可以挂到另一个 Java 虚拟机的扩展,通过 Attach API 可以直接将自己的代码挂载到另一个 Java 虚拟机中运行, 比如: 我可以在写一段 Java 程序监听 8080 端口的 HTTP 协议, 通过 Attach API 挂载到另一个没有监听8080端口的 Java 进程

    1. Java Instrumentation

    Java Instrumentation 允许 Java 程序通过 Agent 来检测已经 Java 程序的运行,可以通过重写 Java bytecode 的方式, 对现有的类进行替换或者改写。比如如下代码:

    public class Test {
      public void work(){
        doWork();
      }
    }
    

    可以被改写成:

    public class Test {
      public void work(){
        final long startTs = System.currentTimeMillis();
        try {
          doWork();
        } finally{
          final long duration = System.currentTimeMillis() - startTs;
          System.out.println("work duration: " + duration);
        } 
      }
    }
    

    那如何实现 Java Bytecode 的改写呢? 这就不得不提到另一个神器: ASM

    1. ASM
      众所周知, Java 编译器将 .java 文件编译成 .class 文件。.class 遵循 Java Virtual Machine Specification。 既然有了规范,就可以有 Library 可以去解析 .class 文件。 ASM 就是这样一个 Java Library, 用来解析Java 的 bytecode, 也就是 .class 文件。
      不过说实话, 如果不对着 JVM 规范,用 ASM 解析字节码很痛苦。好消息是同样有牛人看不下去了,开发了一个新的 Library: ByteBuddy, 简化了语义,比如:
    1.  Class<?> dynamicType = new ByteBuddy()
    2.    .subclass(Object.class)
    3.    .method(ElementMatchers.named("toString"))
    4.    .intercept(FixedValue.value("Hello World!"))
    5.    .make()
    6.    .load(getClass().getClassLoader())
    7.    .getLoaded();
    8.   
    9.  assertThat(dynamicType.newInstance().toString(), is("Hello World!"));
    

    有兴趣的同学可以用 ASM 实现同样的功能对比一下。

    1. Java Management Extension

    简称 JMX, 简单概括来说, JMX 就是一套可以在运行时获取大多数 JVM 状态的接口,比如 GC、线程、ClassLoading 信息等

    1. 几个有用的 Linux 命令
    • pidstat: 用来获取进程的 IO 和 CPU 占用信息
    • top: 老牌工具,最近有新兴工具 htop、iotop 等

    基础啰嗦完, 我们从安装、方法拦截、简化其他工具三个方面来对比simple-profiler 和 greys-anotomy。

    安装

    simple-profiler

    simple-profiler 是参照 BTrace, 因此跟 BTrace 一样, 需要下载对应的 tar 包放到目标服务器上解压缩

    greys-anotomy

    一行 bash 脚本, 自动下载最新的包并安装。

    curl -sLk http://ompc.oss.aliyuncs.com/greys/install.sh|sh
    

    安装过程对比结论:

    • simple-profiler 简直就是石器时代
    • greys-anotomy 才是先进生产力代表

    拦截 Java 方法

    simple-profiler 拦截

    支持两种方式:改写一层 Java 字节码获取方法耗时(我起名叫: simple profile 模式)和改写 N 层字节码获取某方法 N 层调用栈每个方法的耗时(我起名叫: detail profile 模式)。
    比如你怀疑 Test 类有性能问题, 通过 simple profile 方式, 发现 Test 类中的 work 方法非常耗时。如果想进一步知道 work 方法中调用了哪个方法导致了耗时很长, 就需要通过 detail profile 模式,将 work 方法调用的所有的其他类的方法改写字节码, 统计耗时, 找出真凶。

    实现方式很简单:

    • simple profile 模式下, 仅仅找到 Test 类的源代码,将所有方法改写, 统计耗时
    • detail 模式下,有些麻烦。通过解析 Test 类的 work方法, 迭代方式直至到达第 N 层,将所有涉及的类的方法改写,并且在 ThreadLocal 中使用标记, 只有上层是 Test 类的 work 方法时才统计时间,避免误判。

    greys-anotomy 拦截

    不仅仅支持 simple-profiler 的所有用过,还支持参数解析,也就是说支持仅仅在参数 == 某些值的时候才进行统计, 非常实用。
    不仅如此,还可以通过 tt 命令,记录调用历史,供后续分析。这个功能非常实用,在 troubleshooting 时很有可能满足条件的调用转瞬即逝, 一旦没有留下现场,再等一次那才忧伤。

    方法拦截对比结论:

    还用说么, 肯定是 greys-anotomy 强大到一塌糊涂啊

    封装其他工具

    simple-profiler

    • 封装了 jstack 和 pidstat, 可以直接查看 IO 消耗最大的线程的 stacktrace
    • 封装了 jstack 和 top,直接查看 CPU 占用最高的线程的 stacktrace
    • 封装了 jmap,直接统计内存占用信息
    • 封装了 jinfo,直接查看 JVM 信息

    greys-anotomy

    貌似没有封装任何其他工具。

    封装工具总结:

    • 貌似是 simple-profiler 略胜一筹,但不是 simple-profiler 做的更好, 而是 greys-anotomy 的作者根本就没想做这层封装。

    交互方式

    simple-profiler

    • 使用 server-client 模式, server 是一个 web 程序
    • 客户端通过 server_url 指定 server 地址,attach 成功后自动注册到 server
    • 用户通过 web 页面跟 JVM 交互

    greys-anotomy

    greys-anotomy greys-anotomy
    • 仅仅支持命令行,roadmap 中说 2.x.x 会支持图形客户端
    • 支持远程操作

    交互方式总结

    • simple-profiler 虽然支持网页操作,但页面实在做的太烂,并且没有历史回溯功能,非常简陋
    • greys-anotomy 虽然仅仅有命令行,但用户都是工程师,并无大碍

    总结

    • 神器 greys-anatomy 值得所有 Java 程序员拥有,没事翻翻它的源码,也一定受益匪浅。

    • 我写的 simple-profiler 已经落灰,但写的过程中也学些到很多知识。还是那个原则:

      好东西不重写一遍永远不知道好东西有多好,当年的 "Hello World" 难道你没重写么?
      

    最后, 贴几行 simple-profiler 的log,纪念那些个无眠的夜……

    profiler-client    bash  bin/profiler_run.sh --pid 68189
    SimpleProfiler [2016-08-14 13:45:44.255]  [INFO] attach cost(ms): 321
    
    SimpleProfiler [2016-08-14 13:45:44.453]  [INFO]
    
    Simple Profiler started at 192.168.0.111:8030
    

    -- EOF --

    相关文章

      网友评论

        本文标题:跟 grays-anatomy 比, 才知道自己写的东西有多幼稚

        本文链接:https://www.haomeiwen.com/subject/prtpsttx.html