1.根據(jù)官方啟動(dòng)腳本佩脊,我們發(fā)現(xiàn)這樣一行
-javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar
-Dpinpoint.agentId=xxx
-Dpinpoint.applicationName=xxx
- javaagent
pinpoint基于java instrument實(shí)現(xiàn),java instrument定義:開(kāi)發(fā)者可以構(gòu)建一個(gè)獨(dú)立于應(yīng)用程序的代理程序(Agent)顶吮,用來(lái)監(jiān)測(cè)和協(xié)助運(yùn)行在 JVM 上的程序,甚至能夠替換和修改某些類(lèi)的定義粪薛。
參考文檔:https://blog.csdn.net/GV7lZB0y87u7C/article/details/79860776 - pinpoint-bootstrap-$VERSION.jar
找到pinpoint-bootstrap源碼包悴了,我們找到帶有premain方法的類(lèi)PinpointBootStrap
classPathResolver.verify()
在這個(gè)方法里,可以知道加載了這四個(gè)jar
static final Pattern DEFAULT_AGENT_PATTERN = Pattern.compile("pinpoint-bootstrap" +VERSION_PATTERN + "\\.jar");
static final Pattern DEFAULT_AGENT_COMMONS_PATTERN = Pattern.compile("pinpoint-commons" + VERSION_PATTERN + "\\.jar");
static final Pattern DEFAULT_AGENT_CORE_PATTERN = Pattern.compile("pinpoint-bootstrap-core" + VERSION_PATTERN + "\\.jar");
static final Pattern DEFAULT_AGENT_CORE_OPTIONAL_PATTERN = Pattern.compile("pinpoint-bootstrap-core-optional" + VERSION_PATTERN + "\\.jar");
利用1.6之后的java新特性加載pinpoint-commons,bootstrap-core,pinpoint-bootstrap-core-optional三個(gè)jar
appendToBootstrapClassLoader(instrumentation, bootstrapJarFile);
PinpointStarter.java加載插件
// PinpointStarter的start方法加載插件的路徑
URL[] pluginJars = classPathResolver.resolvePlugins();
...
// 加載插件
TraceMetadataLoaderService typeLoaderService = new DefaultTraceMetadataLoaderService(pluginJars, loggerFactory);
通過(guò)PluginLoader加載违寿,封裝ClassLoader
public static <T> List<T> load(Class<T> serviceType, URL[] urls) {
URLClassLoader classLoader = createPluginClassLoader(urls, ClassLoader.getSystemClassLoader());
return load(serviceType, classLoader);
}
這里加載的是TraceMetadataProvider.class這個(gè)接口的所有插件里面的實(shí)現(xiàn)類(lèi)并執(zhí)行setup方法
然后將setup加載的svicetype與code加載進(jìn)來(lái)并存儲(chǔ)
ServiceTypeRegistryService serviceTypeRegistryService = new DefaultServiceTypeRegistryService(typeLoaderService, loggerFactory);
AnnotationKeyRegistryService annotationKeyRegistryService = new DefaultAnnotationKeyRegistryService(typeLoaderService, loggerFactory);
之后加載你的額外配置让禀,默認(rèn)加載pinpoint.config
// 加載pinpoint額外配置,先從虛擬機(jī)獲取配置文件地址陨界,沒(méi)有默認(rèn)pinpoint.config位置
String configPath = getConfigPath(classPathResolver);
...
// 日志地址存入系統(tǒng)
saveLogFilePath(classPathResolver);
// 版本存入系統(tǒng)
savePinpointVersion();
// 加載配置并賦值
ProfilerConfig profilerConfig = DefaultProfilerConfig.load(configPath);
// 創(chuàng)建pinpoint-commons,bootstrap-core,pinpoint-bootstrap-core-optional三個(gè)jar的類(lèi)加載器
AgentClassLoader agentClassLoader = new AgentClassLoader(libUrlList.toArray(new URL[libUrlList.size()]));
創(chuàng)建pinpointAgent
// 創(chuàng)建代理選項(xiàng)
AgentOption option = createAgentOption(agentId, applicationName, profilerConfig, instrumentation, pluginJars, bootstrapJarFile, serviceTypeRegistryService, annotationKeyRegistryService);
// 獲取代理類(lèi),默認(rèn)DefaultAgent
Agent pinpointAgent = agentClassLoader.boot(option);
創(chuàng)建過(guò)程中涉及字節(jié)碼加載技術(shù)的選擇與插件的執(zhí)行
// 攔截器初始大小設(shè)置
createInterceptorRegistry(agentOption)
// 指定字節(jié)碼加載技術(shù),支持ASM與JAVASSIST
this.classPool = createInstrumentEngine(agentOption, interceptorRegistryBinder);
...
// 生成插件
final List<ProfilerPlugin> plugins = PluginLoader.load(ProfilerPlugin.class, new URL[] { jar });
// 插件setup方法執(zhí)行
PluginConfig pluginConfig = new PluginConfig(jar, plugin, agent.getInstrumentation(), agent.getClassPool(), agent.getBootstrapJarPaths(), pluginFilterChain);
final DefaultProfilerPluginContext context = setupPlugin(pluginConfig);
// 插件注入TransformTemplate
final TransformTemplate transformTemplate = new TransformTemplate(guardInstrumentContext);
((TransformTemplateAware) plugin).setTransformTemplate(transformTemplate);
// 執(zhí)行插件類(lèi)setup方法痛阻,里面組裝寫(xiě)好的Interceptor信息并放入攔截器鏈InterceptorRegistry
plugin.setup(guardPluginContext);
...
DefaultAgent的start方法處理信息的收集與發(fā)送
// 定時(shí)任務(wù)收集與發(fā)送(兩個(gè)定時(shí)任務(wù)處理)
pinpointAgent.start();
最后優(yōu)雅停機(jī)
// 優(yōu)雅停機(jī)
registerShutdownHook(pinpointAgent);