skywalking源码分析第五篇一server-configuration配置模块启动

本文探讨了OAP Server的配置模块,包括多种配置提供者如Apollo、Consul等,重点剖析了AbstractConfigurationProvider和ConfigWatcherRegister的工作原理。学习如何使用DynamicConfigurationService动态注册和监听配置变化,以及如何通过用户自定义ConfigChangeWatcher实现配置管理。

Configuration模块主要用于提供oapServer配置参数

支持基于外部中间件的动态配置[可动态修改刷新配置]
默认的非动态配置

application.ymlserver-configuration
在这里插入图片描述在这里插入图片描述

配置模块架构图

  • 外部模块创建配置类[继承ConfigChangeWatcher],并通过配置模块registerConfigChangeWatcher实现配置注册
  • 配置模块根据具体Provider实现调用ConfigChangeWatcher.notify通知配置变更
  • 配置的监听通过pull模式,60秒一次主动读取
Provider名称作用
NoneConfigurationProvider不支持动态监听配置修改
AbstractConfigurationProvider动态配置类基类
ApolloConfigurationProvider监听Apollo配置
ConsulConfigurationProvider监听consul配置
EtcdConfigurationProvider监听etcd配置
GRPCConfigurationProvider支持grpc服务读取
NacosConfigurationProvider监听nacos配置
ZookeeperConfigurationProvider监听zk配置

在这里插入图片描述

源码分析一ConfigurationProvider.prepare

  • 根据具体Provider初始化具体的ConfigWatcherRegister
  • ConfigWatcherRegister作为DynamicConfigurationService注册到Provider
public abstract class AbstractConfigurationProvider extends ModuleProvider {
    注册该服务configWatcherRegister,该服务负责扫描ConfigChangeWatcher变更,并调用其notify方法
    private ConfigWatcherRegister configWatcherRegister;
    @Override public void prepare() throws ServiceNotProvidedException, ModuleStartException {
        初始化配置注册器[负责定时拉取不同中间件的配置 调用watcher监听器更新配置]
        configWatcherRegister = initConfigReader();
        注册配置注册器
        this.registerServiceImplementation(DynamicConfigurationService.class, configWatcherRegister);
    }
}



public class ZookeeperConfigurationProvider extends AbstractConfigurationProvider {
    private ZookeeperServerSettings settings;
    yml 对应的Provider中取得相关配置
    @Override
    public ModuleConfig createConfigBeanIfAbsent() {
        return settings;
    }

    @Override
    protected ConfigWatcherRegister initConfigReader() throws ModuleStartException {
        try {
            zk的配置信息初始化zkClient
            return new ZookeeperConfigWatcherRegister(settings);
        } catch (Exception e) {
            throw new ModuleStartException(e.getMessage(), e);
        }
    }
}

源码分析一 configWatcherRegister.start

provider 的notifyAfterCompleted调用配置监听注册器的start方法

  • 每60秒执行一次readConfig进行远程配置拉取
  • 不同的中间件readConfig实现不同,zk则读取zk信息,apollo则读取Apollo
  • 调用ConfigChangeWatcher.notify实现注册变更通知
  • ConfigChangeWatcher子类为用户自定义配置类
  • 定义好ConfigChangeWatcher子类通过registerConfigChangeWatcher注册到配置模块中,从而支持监听功能

public abstract class ConfigWatcherRegister implements DynamicConfigurationService {
    @Override synchronized public void registerConfigChangeWatcher(ConfigChangeWatcher watcher) {
        if (isStarted) {
            throw new IllegalStateException("Config Register has been started. Can't register new watcher.");
        }

        WatcherHolder holder = new WatcherHolder(watcher);
        if (register.containsKey(holder.getKey())) {
            throw new IllegalStateException("Duplicate register, watcher=" + watcher);
        }
        包含相关的ConfigChangeWatcher
        register.put(holder.getKey(), holder);
    }

    public void start() {
        isStarted = true;
        configSync();
        logger.info("Current configurations after the bootstrap sync." + LINE_SEPARATOR + register.toString());60秒执行一次调度
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
            new RunnableWithExceptionProtection(this::configSync,
                t -> logger.error("Sync config center error.", t)), syncPeriod, syncPeriod, TimeUnit.SECONDS);
    }

    定时同步远程配置的数据
    void configSync() {
        读取远程配置信息
        ConfigTable configTable = readConfig(register.keys());

        configTable.getItems().forEach(item -> {
            String itemName = item.getName();
            其他模块注册的ConfigChangeWatcher
            WatcherHolder holder = register.get(itemName);
            ConfigChangeWatcher watcher = holder.getWatcher();
            String newItemValue = item.getValue();
            ...... 删除部分代码便于阅读
            触发ConfigChangeWatcher监听
            watcher.notify(new ConfigChangeWatcher.ConfigChangeEvent(null, ConfigChangeWatcher.EventType.DELETE));
           
        });
    }

    读取远程配置的信息
    public abstract ConfigTable readConfig(Set<String> keys);

}

总结

  • 静态配置模块为NoneConfigurationProvider,内部空实现
  • 配置模块为其他模块提供配置方式
提供配置方式用户自定义配置
DynamicConfigurationService dynamicConfigurationService = getManager().find(ConfigurationModule.NAME).provider().getService(DynamicConfigurationService.class);ConfigChangeWatcher通过成员变量定义配置
dynamicConfigurationService.registerConfigChangeWatcher(用户自定义配置);通过实现notify修改配置
### 关于 SkyWalking 源码解析与架构设计 #### 1. 配置初始化过程 SkyWalking Agent 的启动流程始于配置初始化阶段,在此期间会读取并解析 `agent.config` 文件中的各项设置。这工作由 `SnifferConfigInitializer.initialize` 方法完成,该方法负责加载和解释配置项以指导后续操作的执行[^3]。 #### 2. 插件机制及其扩展性 SkyWalking 设计之初就考虑到了广泛的兼容性和可扩展性需求,因此内置了对于多种流行框架的支持能力,比如 Dubbo、gRPC 和 SOFARPC 等国内常用的服务治理工具。不仅如此,社区成员也在持续贡献新的插件来增强其对接其他技术栈的能力[^2]。 #### 3. 数据处理模块之缓冲策略 为了优化性能表现以及应对高并发场景下的数据流管理挑战,SkyWalking 实现了套灵活高效的缓冲区管理方案——即通过定义不同的 BufferStrategy 来控制如何存储临时性的追踪记录或其他监控指标信息。这种灵活性允许用户根据不同应用场景调整最佳实践参数设定[^4]。 ```java // 示例:自定义BufferStrategy实现类 public class CustomBufferStrategy implements BufferStrategy { @Override public void offer(Object element) { // 自定义入队逻辑... } @Override public Object poll() { // 自定义出队逻辑... return null; } } ``` #### 4. 启动流程概述 整个Agent启动过程中涉及多个重要环节,首先是上述提到过的配置初始化;之后还包括但不限于服务发现、探针注入等功能模块依次被激活并进入正常运行状态。这些步骤共同构成了个完整的生命周期管理体系,确保各个部分能够协同作业从而达成预期目标[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值