skywalking 启动流程(一)

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中。

猜你喜欢

转载自blog.csdn.net/wangyang_software/article/details/86075289