当前位置 : 主页 > 编程语言 > java >

源码角度了解Skywalking之服务端OAP的启动流程

来源:互联网 收集:自由互联 发布时间:2022-10-15
源码角度了解Skywalking之服务端OAP的启动流程 Skywalking的服务端OAP的逻辑对应oap-server模块,入口是server-starter子模块的OAPServerStartUp类,直接调用了server-bootstrap子模块的OAPServerBootstrap的s

源码角度了解Skywalking之服务端OAP的启动流程

Skywalking的服务端OAP的逻辑对应oap-server模块,入口是server-starter子模块的OAPServerStartUp类,直接调用了server-bootstrap子模块的OAPServerBootstrap的start()方法

OAPServerBootstrap的start()方法:

public static void start() { String mode = System.getProperty("mode"); RunningMode.setMode(mode); ApplicationConfigLoader configLoader = new ApplicationConfigLoader(); ModuleManager manager = new ModuleManager(); try { ApplicationConfiguration applicationConfiguration = configLoader.load(); manager.init(applicationConfiguration); manager.find(TelemetryModule.NAME).provider().getService(MetricsCreator.class).createGauge("uptime", "oap server start up time", MetricsTag.EMPTY_KEY, MetricsTag.EMPTY_VALUE) // Set uptime to second .setValue(System.currentTimeMillis() / 1000d); if (RunningMode.isInitMode()) { logger.info("OAP starts up in init mode successfully, exit now..."); System.exit(0); } } catch (Throwable t) { logger.error(t.getMessage(), t); System.exit(1); } }
  • 读取系统配置的mode值,如果值为init表示初始化模式,做所有初始化的事情。如果值是no-init,表示非初始化模式,不进行存储初始化
  • 创建ApplicationConfiguration对象,通过load()方法加载配置文件,具体是读取resources文件夹下的application.yml文件,然后读取系统配置,覆盖读取的application.yml文件的值
  • 初始化给定的模块
  • 查找指定Module中的获取相应Service,创建仪表类型指标实例标记启动时间。
  • 如果是初始化模式,初始化成功后会退出OAP服务
  • 我们具体看一下初始化模块

    初始化模块

    ModuleManager负责在收集器中的所有ModuleDefine

    ModuleManager的init()方法:

  • 获取配置所有的模块集合,配置文件中配置的都是模块名,这些都是在ModuleDefine的实现类中定义了,比如配置文件中的core对应的是ModuleDefine实现类CoreModule
  • 通过SPI机制加载ModuleDefine的实现类
  • 通过SPI机制加载ModuleProvider的实现类
  • 遍历所有的ModuleDefine实现类,与配置文件中定义的实现类匹配,匹配成功调用prepare()方法进行初始化,否则放入map集合loadedModules中进行记录
  • 添加完成准备阶段的标记
  • 创建BootstrapFlow对象,启动ModuleManager对象,完成后调用notifyAfterCompleted()方法通知所有的ModuleProvider实例,表示可以对外提供服务了
  • ModuleDefine的准备阶段

    ModuleDefine实例的prepare()方法是运行模块的准备阶段,这个方法中也会找到所有潜在的提供者,让他们也进入准备阶段

    ModuleDefine的prepare()方法:

  • 遍历SPI机制加载的moduleProviderLoader实现类,与配置文件中模块定义的实现类匹配,匹配成功设置ModuleProvider实例的ModuleManager和当前ModuleDefine
  • 调用ModuleProvider的prepare()方法让提供者也进入准备状态,prepare()方法是ModuleProvider的抽象方法,具体方法由它的子类来实现,每个模块的prepare()方法也不同,每个模块仅对应一个ModuleProvider
  • BootstrapFlow创建、启动与通知

    在初始化过程中,创建BootstrapFlow对象,BootstrapFlow的构造方法中创建LinkedList对象用链表集合记录模块的启动顺序,模块之间可能存在依赖,所以需要调用makeSequence()方法设定模块的加载顺序。

    BootstrapFlow的start()方法:

    void start( ModuleManager moduleManager) throws ModuleNotFoundException, ServiceNotProvidedException, ModuleStartException { for (ModuleProvider provider : startupSequence) { 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()); provider.requiredCheck(provider.getModule().services()); provider.start(); } }

    遍历所有的ModuleProvider:

  • 根据ModuleProvider需要的模块名判断是否ModuleProvider中是否有需要的模块,如果没有抛出异常
  • 检测模块的service是否实现了,如果没有会抛出异常
  • 启动ModuleProvider
  • 所有的ModuleProvider依次启动后回调执行notifyAfterCompleted()方法

    总结

    这篇文章主要讲了Skywalking的服务端OAP的启动流程,入口是server-starter模块的OAPServerStartUp类的main()方法,这一启动过程主要做的是加载server-bootstrap模块中的application.yml定义的模块定义、模块配置,然后相对应的ModuleProvider依次按顺序进行启动

    ❤️ 感谢大家

    如果你觉得这篇内容对你挺有有帮助的话:

  • 欢迎关注我❤️,点赞
  • 网友评论