skywalking collector 整体代码比较清晰,采用模块化开发。
启动模块server-starter,此模块代码十分简单,主要实现了加载配置,并启动各个模块的功能。
OAPServerStartUp 该类是这个程序的入口。
public static void main(String[] args) {
//配置文件
ApplicationConfigLoader configLoader = new ApplicationConfigLoader();
ModuleManager manager = new ModuleManager();
try {
//读取配置
ApplicationConfiguration applicationConfiguration = configLoader.load();
//初始化给定的模块
manager.init(applicationConfiguration);
String mode = System.getProperty("mode");
if ("init".equals(mode)) {
logger.info("OAP starts up in init mode successfully, exit now...");
System.exit(0);
}
} catch ( Exception e) {
System.exit(1);
}
}
首先加载配置,配置文件信息加载,并封装到配置对象中。
@Override public ApplicationConfiguration load() throws ConfigFileNotFoundException {
ApplicationConfiguration configuration = new ApplicationConfiguration();
//加载配置文件application.yml
//配置文件分位三层,module、provider、property
this.loadConfig(configuration);
//覆盖默认配置文件,在环境变量中获取,只覆盖存在的(不能新加)。
this.overrideConfigBySystemEnv(configuration);
return configuration;
}
其次是初始化模块信息,这个功能也循环加载每个模块。
public void init(ApplicationConfiguration applicationConfiguration) throws ModuleNotFoundException, ProviderNotFoundException, ServiceNotProvidedException, CycleDependencyException, ModuleConfigException, ModuleStartException {
//读取配置中的模块名称(可通过环境变量修改)。
String[] moduleNames = applicationConfiguration.moduleList();
//通过SPI加载模块
//org.apache.skywalking.oap.server.core.storage.StorageModule
//org.apache.skywalking.oap.server.core.cluster.ClusterModule
//org.apache.skywalking.oap.server.core.CoreModule
//org.apache.skywalking.oap.server.core.query.QueryModule
//org.apache.skywalking.oap.server.core.alarm.AlarmModule
//org.apache.skywalking.oap.server.receiver.istio.telemetry.module.IstioTelemetryReceiverModule
//org.apache.skywalking.oap.server.receiver.jvm.module.JVMModule
//org.apache.skywalking.aop.server.receiver.mesh.MeshReceiverModule
//org.apache.skywalking.oap.server.receiver.register.module.RegisterModule
//org.apache.skywalking.oap.server.receiver.trace.module.TraceModule
//org.apache.skywalking.oap.server.receiver.zipkin.ZipkinReceiverModule
//org.apache.skywalking.oap.server.library.module.TestModule
//org.apache.skywalking.oap.server.library.module.BaseModuleA
//org.apache.skywalking.oap.server.library.module.BaseModuleB
ServiceLoader<ModuleDefine> moduleServiceLoader = ServiceLoader.load(ModuleDefine.class);
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);
}
//调用模块的预处理方法,在模块抽象类中,具体的功能,初始化模块的provider,
//初始化每个模块的配置对象-通过反射机制,把配置填写到模块的配置对象中,
//调用provider的prepare方法,初始化provider。
//这个方法中不能跨模块,否则会出现不可预知的错误。
newInstance.prepare(this, applicationConfiguration.getModuleConfiguration(moduleName));
loadedModules.put(moduleName, newInstance);
moduleList.remove(moduleName);
}
}
}
// Finish prepare stage
isInPrepareStage = false;
if (moduleList.size() > 0) {
throw new ModuleNotFoundException(moduleList.toString() + " missing.");
}
//模块化的启动流程。
//首先检查Module,provider的依赖关系,启动先后顺序
BootstrapFlow bootstrapFlow = new BootstrapFlow(loadedModules);
//provider的启动方法
bootstrapFlow.start(this);
//provider的notifyAfterCompleted方法
bootstrapFlow.notifyAfterCompleted();
}
provider的加载过程。此过程就是上图中,在加载每个模块时调用prepare方法中实现的。也是通过SPI方式实现。
void prepare(ModuleManager moduleManager,ApplicationConfiguration.ModuleConfiguration configuration) throws ProviderNotFoundException, ServiceNotProvidedException, ModuleConfigException, ModuleStartException {
//通过SPI查询所有的ModuleProvider类
ServiceLoader<ModuleProvider> moduleProviderLoader = ServiceLoader.load(ModuleProvider.class);
boolean providerExist = false;
for (ModuleProvider provider : moduleProviderLoader) {
//对比查找本模块的provider
if (!configuration.has(provider.name())) {
continue;
}
providerExist = true;
if (provider.module().equals(getClass())) {
ModuleProvider newProvider;
try {
newProvider = provider.getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new ProviderNotFoundException(e);
}
//Set方法,provide持有该模块、moduleManager的引用类型
newProvider.setManager(moduleManager);
newProvider.setModuleDefine(this);
loadedProviders.add(newProvider);
}
}
if (!providerExist) {
throw new ProviderNotFoundException(this.name() + " module no provider exists.");
}
for (ModuleProvider moduleProvider : loadedProviders) {
logger.info("Prepare the {} provider in {} module.", moduleProvider.name(), this.name());
try {
//填充provider的配置对象
copyProperties(moduleProvider.createConfigBeanIfAbsent(), configuration.getProviderConfiguration(moduleProvider.name()), this.name(), moduleProvider.name());
} catch (IllegalAccessException e) {
throw new ModuleConfigException(this.name() + " module config transport to config bean failure.", e);
}
//预处理类
moduleProvider.prepare();
}
}
至此,启动的流程结束。核心的实现分布在每个模块中的provider中。