Zorka源码阅读与讲解(2)怎样实现Online Reconfiguration?

也同样是想通过这篇日志,讲讲在Java中怎么实现插桩的在线配置和管理。在之前这篇日志中,我简单介绍了Online
Reconfiguration的基本效果,这里讲讲Zorka是怎么实现的(其实远比大家想想的要简单)。

之前那篇日志中我讲过,我们就从reload这个方法入手。最简单的方法是,直接在Eclipse中搜索reload这个方法。Search——File——Containing Text中填入reload,然后在Scope中选择Enclosing Projects,点Search,就会出现一些match的结果,我们简单浏览一下,发现有个类叫ZorkaControlMBean,点开一看,发现只是个接口。我们在这个接口的名字上点右键——References——Project,就可以看到原来只有一个ZorkaControl类实例化了这个接口,看到这个类的reload方法只是调用了AgentInstance的对象的同名方法。

所以我们只需要看看AgentInstance这个类的reload方法:这个方法读起来也很简单,我就不详细展开介绍了,唯一需要注意的就是这条语句:

getRetransformer().retransform(oldSet, newSet, false);

我们可以看到,实际上就是这条语句实现了真正的Reconfiguration,按照一样的方法,可以找到retransform这个方法实际上是在RealSpyRetransformer的retransform这个方法中进行了实现,AgentInstance这个类中的成员变量:

private SpyRetransformer retransformer;

实际上是RealSpyRetransformer这个类的对象。我们看一下RealSpyRetransformer这个类中的retransform这个方法,重点看一下这一条语句:

instrumentation.retransformClasses(classes.toArray(new Class[0]));

原来直接调用的是instrumentation对象的retransformClasses这个方法。关于这个方法,我们可以参看这里:http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html 对这个方法的介绍:This
function facilitates the instrumentation of already loaded classes. When classes are initially loaded or when they are redefined, the initial class file bytes can be transformed with the ClassFileTransformer. This function reruns the transformation process
(whether or not a transformation has previously occurred). 看到这里相信大家就都明白了,原来Zorka说到底只是调用JDK的标准API实现了Online Reconfiguration。需要指出的是,这个方法是JDK 1.6之后才增加的,并不适用于JDK 1.5。

关于这些方法从JDK 1.5到8.0的演化,大家可以参看一下链接:

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/instrument/Instrumentation.html

http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/Instrumentation.html

可以看到,从JDK 1.5中,这个接口只有7个方法,从JDK 6开始稳定在15个方法。

时间: 2024-08-04 01:45:32

Zorka源码阅读与讲解(2)怎样实现Online Reconfiguration?的相关文章

Memcache-Java-Client-Release源码阅读(之七)

一.主要内容 本章节的主要内容是介绍Memcache Client的Native,Old_Compat,New_Compat三个Hash算法的应用及实现. 二.准备工作 1.服务器启动192.168.0.106:11211,192.168.0.106:11212两个服务端实例. 2.示例代码: String[] servers = { "192.168.0.106:11211", "192.168.0.106:11212" }; SockIOPool pool =

Flume-NG源码阅读之SourceRunner,及选择器selector和拦截器interceptor的执行

在AbstractConfigurationProvider类中loadSources方法会将所有的source进行封装成SourceRunner放到了Map<String, SourceRunner> sourceRunnerMap之中.相关代码如下: 1 Map<String, String> selectorConfig = context.getSubProperties( 2 BasicConfigurationConstants.CONFIG_SOURCE_CHANNE

【原】AFNetworking源码阅读(六)

[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AFNetworking的网络安全策略,尤其指HTTPS(大家可以先简单了解下HTTPS).再一个就是分析下AFNetworkReachabilityManager文件,看看AFNetworking如何解决网络状态的检测. 2. AFSecurityPolicy - 网络安全策略 之前我们在AFURLS

【原】AFNetworking源码阅读(四)

[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDelegate类所实现的NSURLSession相关的代理方法,甚至连dataTask.uploadTask.downloadTask这几个基本概念也没说.这一篇就是为了集中消灭这些遗留问题. 2. AFURLSessionManagerTaskDelegate的代理方法 此处实现的仍然是NSURLS

Flume-NG源码阅读之AvroSink

org.apache.flume.sink.AvroSink是用来通过网络来传输数据的,可以将event发送到RPC服务器(比如AvroSource),使用AvroSink和AvroSource可以组成分层结构.它继承自AbstractRpcSink  extends AbstractSink implements Configurable这跟其他的sink一样都得extends AbstractSink implements Configurable,所以重点也在confgure.start.

【原】SDWebImage源码阅读(五)

[原]SDWebImage源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 前面的代码并没有特意去讲SDWebImage的缓存机制,主要是想单独开一章节专门讲解缓存.之前我们也遇到一些缓存的属性和方法,比如storeImage.queryDiskCacheForKey.memCache等等. SDWebImage的缓存分为两个部分,一个内存缓存,使用NSCache实现,另一个就是硬盘缓存(disk),使用NSFileManager实现. 不过这么多函数,

spark.mllib源码阅读-分类算法4-DecisionTree

本篇博文主要围绕Spark上的决策树来讲解,我将分为2部分来阐述这一块的知识.第一部分会介绍一些决策树的基本概念.Spark下决策树的表示与存储.结点分类信息的存储.结点的特征选择与分类:第二部分通过一个Spark自带的示例来看看Spark的决策树的训练算法.另外,将本篇与上一篇博文"spark.mllib源码阅读bagging方法"的bagging子样本集抽样方法结合,也就理解了Spark下的决策森林树的实现过程. 第一部分: 决策树模型 分类决策树模型是一种描述对实例进行分类的树形

Android系统源码阅读(12):InputChannel的注册过程

Android系统源码阅读(12):InputChannel的注册过程 请对照AOSP版本:6.0.1_r50. InputManager可以获得输入事件并分发,Activity需要处理这些输入事件.那么,这两者之间如何建立的连接呢?这就需要InputChannel作为桥梁建立两者之间的通道. 1. ViewRootImpl创建InputChannel 这里ViewRoot类已经消失了,由ViewRootImpl替代.Activity在创建时会将自己的DecorView设置给对应的ViewRoo

Nutch源码阅读进程3---fetch

走了一遍Inject和Generate,基本了解了nutch在执行爬取前的一些前期预热工作,包括url的过滤.规则化.分值计算以及其与mapreduce的联系紧密性等,自我感觉nutch的整个流程是很缜密的,起码从前面两个过程看是这样的. 前期回顾:上一期主要是讲解了nutch的第二个环节Generate,该环节主要完成获取将要抓取的url列表,并写入到segments目录下,其中一些细节的处理包括每个job提交前的输入输出以及执行的map和reducer类具体做了那些工作都可以参考上一篇.接下