读书笔记javatool

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

2016-08-15  本文已影响2214人  haitaoyao

通过比较作者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 命令

基础啰嗦完, 我们从安装、方法拦截、简化其他工具三个方面来对比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

安装过程对比结论:

拦截 Java 方法

simple-profiler 拦截

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

实现方式很简单:

greys-anotomy 拦截

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

方法拦截对比结论:

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

封装其他工具

simple-profiler

greys-anotomy

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

封装工具总结:

交互方式

simple-profiler

greys-anotomy

greys-anotomy greys-anotomy

交互方式总结

总结

最后, 贴几行 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 --

上一篇下一篇

猜你喜欢

热点阅读