8.BootService组件分析
2025/9/10大约 1 分钟
8.BootService组件分析
BootService 相当于是skywalking-java客户端中的单独的组件,用于提供特定的功能,不属于agent范畴,但是和agent的插件、agent核心 配合工作,组成一个完整的功能。
如grpc 和服务端通信,Kafka 指标上报,等等。
BootService 管理和加载
BootService由ServiceManager进行管理和加载,
生命周期分为:
- prepare:准备开始
- boot:即start
- onComplete:执行完成
- shutdown:agent 结束时调用,用于释放资源
BootService 的加载
实现:org.apache.skywalking.apm.agent.core.boot.ServiceManager#loadAllServices
通过Java SPI 机制进行加载,通过注解 @DefaultImplementor
和 @OverrideImplementor
来控制最终的实现类使用哪个?
- @DefaultImplementor: 默认显示,允许重复,后来的会覆盖先来的
- @OverrideImplementor: 覆盖实现,只能覆盖 @DefaultImplementor
- 无任何注解,不允许被覆盖,重复定义会报错
生命周期
- prepare
- startup -> BootService#boot
- onComplete
程序结束时调用 shutdown
需要注意的是,这个是执行这些 BootService
生命周期是同步执行的,不是异步处理的。
对于一些处理网络的组件,这就不合适了,比如说Kafka是要一直运行的。另外有些任务是阻塞的,这同样也会把agent的主启动现成卡死。
使用例子
以创建一个卡夫卡生产者对象为例:
org.apache.skywalking.apm.agent.core.kafka.KafkaProducerManager
自己维护了一个线程池用于异步启动Kafka生产者对象,不阻塞主线程执行。
public void boot() {
bootProducerFuture = Executors.newSingleThreadScheduledExecutor(
new DefaultNamedThreadFactory("kafkaProducerInitThread")
).scheduleAtFixedRate(new RunnableWithExceptionProtection(
this,
t -> LOGGER.error("unexpected exception.", t)
), 0, 120, TimeUnit.SECONDS);
}
他在新线程中对Kafka进行了异步启动。
如何使用bootService?
ServiceManager.INSTANCE.findService(ConfigurationDiscoveryService.class);
就是从 LinkedHashMap 中通过全类名 获取 当前类的一个对象,调用其函数。