BTrace,Greys,TProfile性能监控别人看到我看

2016-12-28 新增了Attach的原理介绍参考

innodb系列主要内容差不多完成了,剩下的就不定期更新了,现在接着看监控了,这里的监控不是业务系统监控,这里主要涉及的是coding方面的监控。

为什么还要说监控

前面一篇文章提到的监控主要针对业务监控,数据的模型都以服务画像作为基础,而代码层面的监控主要为解决代码层面的各种问题诞生,比如性能、容量分析等角度。

需要准备点什么呢

首先,先star一下吧,使用的代码demo在这里都能找到,待更新…

https://github.com/xuminwlt/j360-instrumenter-all

基础

java.lang.instrument jdk5+

java Instrumentation指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态,替换和修改类定义等。 Java SE5中使用JVM TI替代了JVM PI和JVM DI。提供一套代理机制,支持独立于JVM应用程序之外的程序以代理的方式连接和访问JVM。java.lang.instrument是在JVM TI的基础上提供的Java版本的实现。 Instrumentation提供的主要功能是修改jvm中类的行为。 Java SE6中由两种应用Instrumentation的方式,premain(命令行)和agentmain(运行时)

具体使用方式参考

http://jiangbo.me/blog/2012/02/21/java-lang-instrument/

权威参考:

http://www.ibm.com/developerworks/cn/java/j-lo-jse61/

https://blogs.oracle.com/CoreJavaTechTips/entry/the_attach_api

关于Attach的原理:
那Attach机制是什么?说简单点就是jvm提供一种jvm进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作,比如说我们为了让另外一个jvm进程把线程dump出来,那么我们跑了一个jstack的进程,然后传了个pid的参数,告诉它要哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如要执行什么操作,传了什么参数等

https://yq.aliyun.com/articles/2950?spm=5176.100239.blogcont67090.20.FoDzCq

工具

性能监控工具的使用基本上使用instrument agent方式对程序进行监控,抛开开发人员自己开发的业务监控工具之外,这里推荐几个更加专业的工具,这些工具都是通过agent方式对程序进行监控,其中TProfile只能通过premain方式和程序一起启动,通过配置参数对程序执行预定义的监控,而后面两个可以通过premain或agentmain方式执行,可以做到运行时监控,具体的逻辑可以通过编写自定义拦截代码进行监控。

  • TProfile
  • BTrace
  • Greys

开搞

TProfile

监控代码方法执行的时间和数量的监控,分别通过输出log日志形式进行监控,性能影响在20%-30%之间

  • 可配置监控的时间范围
  • 可配置监控的方法
  • 可通过tcp远程执行命令

-javaagent:/Users/min_xu/Documents/IdeaProjects/TProfiler/pkg/TProfiler/lib/tprofiler-1.0.1.jar -Dprofile.properties=/Users/min_xu/Documents/IdeaProjects/TProfiler/pkg/TProfiler/lib/profile.properties

tprofile相关的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#log file name
logFileName = tprofiler.log
methodFileName = tmethod.log
samplerFileName = tsampler.log
#basic configuration items
startProfTime = 9:00:00
endProfTime = 13:00:00
eachProfUseTime = 5
eachProfIntervalTime = 50
samplerIntervalTime = 20
port = 50000
debugMode = true
needNanoTime = false
ignoreGetSetMethod = true
#file paths
logFilePath = ${user.home}/logs/${logFileName}
methodFilePath = ${user.home}/logs/${methodFileName}
samplerFilePath = ${user.home}/logs/${samplerFileName}
#include & excludes items
excludeClassLoader = org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader
includePackageStartsWith = com.taobao;com.taobao.common;com.fotoplace
excludePackageStartsWith = com.taobao.sketch;org.apache.velocity;com.alibaba;com.taobao.forest.domain.dataobject

BTrace

从sun剥离了,在github开源,通过远程监控命令监控jvm方法执行的性能,具体使用方式:

  1. 下载 https://github.com/btraceio/btrace

Grays

通过远程监控命令监控jvm方法执行的性能,参考了BTrace


这里提一下google出品的instrumenter的工具

对分配的内存大小进行监控,主要针对new和特殊的构造器+回调进行监控,思考下如果监控对象的动态的内存变化呢?

地址目录是我的maven仓库地址

-javaagent:/Users/min_xu/.m2/repository/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.0/java-allocation-instrumenter-3.0.jar

java -javaagent:/Users/min_xu/.m2/repository/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.0/java-allocation-instrumenter-3.0.jar TestAllocations java -javaagent:/Users/min_xu/.m2/repository/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.0/java-allocation-instrumenter-3.0.jar TestConstructors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {
public static void main(String [] args) throws Exception {
AllocationRecorder.addSampler(new Sampler() {
public void sampleAllocation(int count, String desc, Object newObj, long size) {
System.out.println("I just allocated the object " + newObj
+ " of type " + desc + " whose size is " + size);
if (count != -1) { System.out.println("It's an array of size " + count); }
}
});
for (int i = 0 ; i < 10; i++) {
new String("foo");
}
}
}

构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Test {
static int count = 0;
int x;
Test() {
x = count;
}
public static void main(String[] args) {
try {
ConstructorInstrumenter.instrumentClass(
Test.class, new ConstructorCallback<Test>() {
@Override public void sample(Test t) {
System.out.println(
"Constructing an element of type Test with x = " + t.x);
count++;
}
});
} catch (UnmodifiableClassException e) {
System.out.println("Class cannot be modified");
}
for (int i = 0; i < 10; i++) {
new Test();
}
System.out.println("Constructed " + count + " instances of Test");
}
}

自己也来写一套吧