Java应用监控的原理


Java应用监控的原理

文章插图
 
监控的基本流程
Java应用监控的原理

文章插图
基本流程
采集数据的方式
  1. 有代码侵入(比如:Cat);
  2. 无代码侵入(比如:Skywalking、Pinpoint等);
怎么做到无代码侵入?【Java应用监控的原理】JVMTI(JAVA Virtual machine Tool Interface)是一套由 Java 虚拟机提供的,为 JVM 相关的工具提供的本地编程接口集合 。JVMTI 是从 Java SE 5 开始引入,整合和取代了以前使用的 Java Virtual Machine Profiler Interface (JVMPI) 和 the Java Virtual Machine Debug Interface (JVMDI),而在 Java SE 6 中,JVMPI 和 JVMDI 已经消失了 。JVMTI 提供了一套”代理”程序机制,可以支持第三方工具程序以代理的方式连接和访问 JVM,并利用 JVMTI 提供的丰富的编程接口,完成很多跟 JVM 相关的功能 。事实上,java.lang.instrument 包的实现,也就是基于这种机制的:在 Instrumentation 的实现当中,存在一个 JVMTI 的代理程序,通过调用 JVMTI 当中 Java 类相关的函数来完成 Java 类的动态操作 。除开 Instrumentation 功能外,JVMTI 还在虚拟机内存管理,线程控制,方法和变量操作等等方面提供了大量有价值的函数 。
使用 JVMTI 我们能做两件事:
  1. 在虚拟机启动时,即在main方法之前可以做一些事情(通过 Java agent);
  2. 在虚拟机启动之后,即在main方法之后可以做一些事情(通过 Attach API);
Java agent的作用(探针)javaagent是一个命令,用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义 。有了这样的功能,开发者就可以实现更为灵活的运行时虚拟机监控和 Java 类操作了,这样的特性实际上提供了一种虚拟机级别支持的 AOP 实现方式,使得开发者无需对 JDK 做任何升级和改动,就可以实现某些 AOP 的功能了 。
Java agent的使用
通过 java.lang.instrument.Instrumentation 来实现 。
1.编写premain函数
public static void premain(String agentArgs, Instrumentation inst); [1]public static void premain(String agentArgs); [2]其中,[1] 的优先级比 [2] 高,将会被优先执行([1] 和 [2] 同时存在时,[2] 被忽略) 。
在这个 premain 函数中,开发者可以进行对类的各种操作 。
agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入 。与 main 函数不同的是,这个参数是一个字符串而不是一个字符串数组,如果程序参数有多个,程序将自行解析这个字符串 。
Inst 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入 。java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,也是这个包的核心部分,集中了其中几乎所有的功能方法,例如类定义的转换和操作等等 。
2.jar文件打包
将这个 Java 类打包成一个 jar 文件,并在其中的 manifest 属性当中加入” Premain-Class”来指定步骤 1 当中编写的那个带有 premain 的 Java 类 。(可能还需要指定其他属性以开启更多功能),如下:
META_INF/MANIFEST.MF文件内容:
Manifest-Version: 1.0 Premain-Class: Premain3.运行
用如下方式运行带有 Instrumentation 的 Java 程序:
java -javaagent:jar 文件的位置 [= 传入 premain 的参数 ]
虚拟机启动后的动态instrument
通过 java.lang.instrument.Instrumentation 和Attach API来实现,Attach API在com.sun.tools.attach包里 。
1.编写agentmain函数
public static void agentmain (String agentArgs, Instrumentation inst); [1] public static void agentmain (String agentArgs); [2]同样,[1] 的优先级比 [2] 高,将会被优先执行 。
2.打包
在.MF文件中增加Agent-Class属性
Agent-Class: AgentMain
3.运行
Java应用监控的原理

文章插图
代码截图
Java应用的监控与诊断工具
  • jconsole, jvisualvm, jprofiler 等
  • MyPerf4J (https://github.com/LinShunKang/MyPerf4J)
  • BTrace (https://github.com/btraceio/btrace)
  • Arthas (https://github.com/alibaba/arthas)
  • Bistoury (https://github.com/qunarcorp/bistoury)
参考https://www.ibm.com/developerworks/cn/java/j-lo-jse61/




    推荐阅读