skywalking 源码分析第三篇⼀oaprver 启动源码分析
⽂章⽬录
上⽂主要介绍了oaprver的微内核架构,本⽂详解其源码实现
源码分析⼀OAPServerBootstrap step-1: 初始化mode为init或者no-init,表⽰是否初始化[example:底层存储组件等]step-2: 初始化ApplicationConfigurationd的加载器和Module的加载管理器step-3 加载yml⽣成ApplicationConfiguration配置
step-4: 初始化模块 通过spi获取所有Module实现,基于yml配置加载spi中存在的相关实现铁塔图片
manager.init包含Module的初始化以及⼦组件ModuleProvider的初始化
源码分析⼀配置加载configLoader.load yml转配置系统环境变量的优先级⾼于l public
class OAPServerBootstrap {祛斑美白
public static void start () {
...... 删除其他代码
step -1: 初始化mode 为init 或者no -init ,表⽰是否初始化[example :底层存储组件等]
String mode = System .getProperty ("mode");
RunningMode .tMode (mode );
step -2: 初始化ApplicationConfigurationd 的加载器和Module 的加载管理器
ApplicationConfigLoader configLoader = new ApplicationConfigLoader ();
ModuleManager manager = new ModuleManager ();
step -3 加载yml ⽣成ApplicationConfiguration 配置
ApplicationConfiguration applicationConfiguration = configLoader .load ();
step -4: 初始化模块 通过spi 获取所有Module 实现,基于yml 配置加载spi 中存在的相关实现
init 包含Module 的初始化以及⼦组件ModuleProvider 的初始化
manager .init (applicationConfiguration );
...... 删除其他代码
}
}
step-1: 读取yml资源step-2: yml配置转成map森林结构step-3: ⼀级配置对应ModuleConfiguration step-4: 为⼆级配置ProviderConfiguration构建properties集合step-5: 构建三级⾄n级Properties结构
step-6: 为⼀级配置添加⼆级配置ProviderConfiguration[包含properties]
源码分析⼀模块加载及启动manager.init
public class ApplicationConfigLoader implements ConfigLoader <ApplicationConfiguration > {
...... 删除其他代码
@Override public ApplicationConfiguration load () throws ConfigFileNotFoundException {
ApplicationConfiguration configuration = new ApplicationConfiguration ();
yml 转ApplicationConfiguration 和ModuleConfiguration 和ProviderConfiguration
this .loadConfig (configuration );
系统环境变量的优先级⾼于application .yml 的优先级
this .overrideConfigBySystemEnv (configuration );
return configuration ;
}
}private
void loadConfig (ApplicationConfiguration configuration ) throws ConfigFileNotFoundException {
...... 删除其他代码
step -1: 读取yml 资源
Reader applicationReader = ResourceUtils .read ("l");
step -2: yml 配置转成map 森林结构
身高体重计算Map <String , Map <String , Map <String , ?>>> moduleConfig = yaml .loadAs (applicationReader , Map .class );
step -3: ⼀级⽬录对应ModuleConfiguration
moduleConfig .forEach ((moduleName , providerConfig ) -> {
ApplicationConfiguration .ModuleConfiguration moduleConfiguration = configuration .addModule (moduleName );
step -4: 为⼆级⽬录ProviderConfiguration 构建properties 集合
providerConfig .forEach ((providerName , propertiesConfig ) -> {
step -5: 构建三级⾄n 级Properties 结构
Properties properties = new Properties ();
if (propertiesConfig != null ) {
propertiesConfig .forEach ((propertyName , propertyValue ) -> {
if (propertyValue instanceof Map ) {
Properties subProperties = new Properties ();
((Map ) propertyValue ).forEach ((key , value ) -> {
subProperties .put (key , value );
replacePropertyAndLog (key , value , subProperties , providerName );
});
properties .put (propertyName , subProperties );
} el {
properties .put (propertyName , propertyValue );
replacePropertyAndLog (propertyName , propertyValue , properties , providerName );
}
});
}
step -6: 为⼀级配置添加⼆级配置ProviderConfiguration [包含properties ]
moduleConfiguration .addProviderConfiguration (providerName , properties );
});
});
.
..... 删除其他代码
}
step-1: 微内核架构,通过spi加载所有实现的Module和ModuleProvider step-2: yml中配置了相关module,源码实现了⼀些模块插件,spi发现所有实现的插件step-3: 初始化引导程序step-4: 启动引导程序 ,完成Provider实现的实例化
step-5: module和moduleProvider启动完毕后通过事件通知调⽤所有ifyAfterCompleted电影天堂
源码分析⼀ModuleDefine.prepare step-1: 设置Module组件的实现loadedProvider step-2: 执⾏具体的Provider的prepare,初始化rvice的相关实现
取两者的交集作为服务启动时需要启动的插件Module 和插件实现ModuleProvider
public void init (
ApplicationConfiguration applicationConfiguration )
throws ModuleNotFoundException , ProviderNotFoundException , ServiceNotProvidedException String [] moduleNames = applicationConfiguration .moduleList ();
step -1: 微内核架构,通过spi 加载所有实现的Module 和ModuleProvider
ServiceLoader <ModuleDefine > moduleServiceLoader = ServiceLoader .load (ModuleDefine .class );
ServiceLoader <ModuleProvider > moduleProviderLoader = ServiceLoader .load (ModuleProvider .class );
step -2: yml 中配置了相关module ,源码实现了⼀些模块插件,spi 发现所有实现的插件
取两者的交集作为服务启动时需要启动的插件Module 和插件实现ModuleProvider
LinkedList <String > moduleList = new LinkedList <>(Arrays .asList (moduleNames ));
for (ModuleDefine module : moduleServiceLoader ) {
for (String moduleName : moduleNames ) {
if (moduleName .equals (module .name ())) {
ModuleDefine newInstance ;
try {
newInstance = module .getClass ().newInstance ();
} catch (InstantiationException | IllegalAccessException e ) {
throw new ModuleNotFoundException (e );
}
step -2.1: 执⾏⽣命周期⽅法prepare [完成⼦组件实例化以及相关⽣命周期执⾏]
newInstance .prepare (this , applicationConfiguration .getModuleConfiguration (moduleName ), moduleProviderLoader );
step -2.2: 加⼊ModuleManager
loadedModules .put (moduleName , newInstance );
moduleList .remove (moduleName );
}
}
}
...... 删除其他代码
step -3: 初始化引导程序
BootstrapFlow bootstrapFlow = new BootstrapFlow (loadedModules );
鸡粥的做法step -4: 启动引导程序 ,完成Provider 实现的实例化
bootstrapFlow .start (this );
step -5: module 和moduleProvider 启动完毕后的事件通知[会打开通信通道等待连接事件等]
bootstrapFlow .notifyAfterCompleted ();
}
module 负责抽象定义,loadedProvider 负责具象实现
源码分析⼀ bootstrapFlow.start
完成module和moduleProvider的加载,依赖关系处理后,需通过prepare初始化moduleProvider 需要通过start启动整个oapServer模块step-1: 检查当前ModuleProvider对应的Module依赖的其他module step-2: 检查所有需要的rvice是不是都完成注册step-3: 启动provider,⽐如es7存储实现则创建esClient,并且根据init模式决定是否在es上初始化索引
public abstract class ModuleDefine implements ModuleProviderHolder {
void prepare (ModuleManager moduleManager , ApplicationConfiguration .ModuleConfiguration configuration ,
ServiceLoader <ModuleProvider > moduleProviderLoader ) throws ProviderNotFoundException , ServiceNotProvidedException , ModuleConfigException for (ModuleProvider provider : moduleProviderLoader ) {
if (!configuration .has (provider .name ())) {
continue ;
}
step -1: 设置Module 组件对应的loadedProvider 实现
module 负责抽象定义,loadedProvider 负责具象实现
if (provider .module ().equals (getClass ())) {
if (loadedProvider == null ) {
loadedProvider = provider ;
loadedProvider .tManager (moduleManager );
loadedProvider .tModuleDefine (this );
} el {
yml 中配置的loadedProvider 不可以超过⼀个
throw new DuplicateProviderException (this .name () + " module has one " + loadedProvider .name () + "[" + loadedProvider .getClass ().getName + provider .name () + "[" + provider .getClass ().getName () + "] is defined as 2nd provider.");
}
}
}
loadedProvider 必须定义
if (loadedProvider == null ) {
throw new ProviderNotFoundException (this .name () + " module no provider exists.");
}
...... 删除其他代码
step -2: 初始化具体的rvice ⼯作集合
⽐如对于存储Storage 来说,prepare 初始化与存储服务的client 创建⼀系列dao 实现类⽤于读写数据
loadedProvider .prepare ();
}
}
总结module负责功能定义,内部定义了rvice集合,rvice代表⼀个⼩的功能Provider是module不同维度的实现,负责注册所有的rviceImpl
oaprver的启动主要包含prepare,start和notify三步骤
扩展点⼀存储StorageModuleElasticarch7Provider prepare主要完成StorageModule中定义的rvice实现与注册start完成esclient启动,并根据mode配置决定是否创建索引
notifyAfterCompleted未做实现
美丽的风景图片
不同的Provider实现不同,⽐如通信组件就会在notifyAfterCompleted中启动netty服务,因为notifyAfterCompleted说明组件已经加载完成,可以对外提供服务,此时启动netty(grpc或者jetty)更为安全
void start (
ModuleManager moduleManager ) throws ModuleNotFoundException , ServiceNotProvidedException , ModuleStartException {
for (ModuleProvider provider : startupSequence ) {
step -1: 检查当前ModuleProvider 对应的Module 依赖的其他module
⽐如存储模块StorageModule 的其中⼀个实现StorageModuleElasticarch7Provider 依赖核⼼模块CoreModule .NAME
String [] requiredModules = provider .
requiredModules ();
if (requiredModules != null ) {
for (String module : requiredModules ) {
if (!moduleManager .has (module )) {
制造英文throw new ModuleNotFoundException (module + " is required by " + provider .getModuleName ()
+ "." + provider .name () + ", but not found.");
}
}
}
logger .info ("start the provider {} in {} module.", provider .name (), provider .getModuleName ());
step -2: 检查所有需要的rvice 是不是存在 Module 不同的provider 有不同的rvices 实现
module 负责定义功能,rvices ⽅法指定了⼀系列rvice 接⼝则module 的实现provider 需要实现该系列的rvice 通过requiredCheck 检查rvice 是否全部实 ⼀般我们在provider .prepare 时通过registerServiceImplementation 注册rviceImpl
provider .requiredCheck (provider .getModule ().rvices ());
step -3: 启动provider ⽐如es7存储实现则创建esClient 并且根据init 模式决定是否在es 上初始化索引
provider .start ();
}
}
public class StorageModuleElasticarch7Provider extends ModuleProvider {
@Override
public String name () {
return "elasticarch7";
}
@Override
public void prepare () throws ServiceNotProvidedException {
/*
public class StorageModule extends ModuleDefine {
@Override public Class[] rvices() {
return new Class[] {
IBatchDAO.class, StorageDAO.class, IRegisterLockDAO.class,
IHistoryDeleteDAO.class,
IServiceInventoryCacheDAO.class, IServiceInstanceInventoryCacheDAO.class,
IEndpointInventoryCacheDAO.class, INetworkAddressInventoryCacheDAO.class,
>领导座位