1、在目标监控进程(要查看该进程popularity中某个方法的性能) ,配置远程调试
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000
2、在arthas 中远程连接上要监控的进程的远程调试,配置如下的连接
127.0.0.1 8000
3、在arthas的控制台中,起动监听进程
as.bat pid 连接上去(pid为popularity 进程的本地进程id)
4、 arthas 源码中自动就会可以远程调用arthas的源码了。
5、使用如下命令进行验证
options save-result true --保存结果
options dump true --把监控的类dum出class文件,然后通过反编译文件进行查看
options json-format true --把控制台输出的方法结果json化
$ watch com.test.mobile.popularity.service.cache.PopularityRankCache getCurNotFinishDay "{params,returnObj}" -x 2 -b --起动监控,输出如下
$ watch com.test.mobile.popularity.service.cache.PopularityRankCache getCurNot
FinishDay "{params,returnObj}" -x 2 -b
Press Ctrl+C to abort.
[dump: G:\workspace\testweb\popularity\mobile-popularity\mobile-popularity-app\.\a
rthas-class-dump\com\test\ent\mobile\popularity\service\cache\PopularityRankCache.
class]
Affect(class-cnt:1 , method-cnt:1) cost in 54993 ms.
ts=2018-11-13 15:53:46;result=[["20181113"],null]
6、反编译生成的class文件,可看到,其实是通过asm的方式,在方法的入口和出口加了一段静态的方法,
private List getCurNotFinishDay(final String curDay) {
Spy.ON_BEFORE_METHOD.invoke(null, new Integer(0), this.getClass().getClassLoader(), "com/test/popularity/service/cache/PopularityRankCache", "getCurNotFinishDay", "(Ljava/lang/String;)Ljava/util/List;", this, new Object[] { curDay });
try {
--------
final List list = hitList;
Spy.ON_RETURN_METHOD.invoke(null, list);
return list;
}
catch (Throwable e) {
final Object o = null;
Spy.ON_RETURN_METHOD.invoke(null, o);
return (List)o;
}
}
catch (Throwable t2) {
Spy.ON_THROWS_METHOD.invoke(null, t2);
throw t2;
}
}
可看到上面添加的静态方法(静态方式的适应是因为调试人员是通过telnet的方式连上去的,是通过threadLocal的方式进行内部数据的管理的)。低层通过SessionImpl中的lock机制,保证监控系统只有唯一一个串行执行的命令
7、源码修改后,可本地打包
mvnw.cmd clean package -DskipTests