当前位置: 首页 > 后端技术 > Java

ApacheSkyWalking报警动态配置源码简析

时间:2023-04-02 01:59:49 Java

AlarmModuleProvider实现了ModuleProvider接口,通过SPI加载。首先调用AlarmModuleProvider的prepare方法做一些预处理:@Overridepublicvoidprepare()throwsServiceNotProvidedException,ModuleStartException{ReaderapplicationReader;尝试{applicationReader=ResourceUtils.read("alarm-settings.yml");}catch(FileNotFoundExceptione){thrownewModuleStartException("无法加载alarm-settings.yml",e);}//先从文件中读取默认配置,这里还没有加载动态配置。RulesReaderreader=newRulesReader(applicationReader);规则rules=reader.readRules();//创建一个AlarmRulesWatcher实例,用于监控和转换动态配置。alarmRulesWatcher=newAlarmRulesWatcher(rules,this);//创建一个NotifyHandler实例,用于处理触发的告警。notifyHandler=newNotifyHandler(alarmRulesWatcher);notifyHandler.init(newAlarmStandardPersistence());//注册到服务实现。this.registerServiceImplementation(MetricsNotify.class,notifyHandler);}随后调用AlarmModuleProvider的start方法:@Overridepublicvoidstart()throwsServiceNotProvidedException,ModuleStartException{//获取动态配置服务,目前(8.2.0)支持动态配置分别是apollo,consul,etcd,k8sconfigmap,nacos,zookeeper,grpc//将之前的AlarmRulesWatcher实例注册到DynamicdynamicConfigurationService.registerConfigChangeWatcher(alarmRulesWatcher);}配置服务中registerConfigChangeWatcher方法的源码在ConfigWatcherRegister抽象类中:@OverridesynchronizedpublicvoidregisterConfigChangeWatcher(ConfigChangeWatcherwatcher){if(isStarted){thrownewIllegalStateException("ConfigRegister已经启动。无法注册新的watcher。");}//使用传入的AlarmRulesWatcher实例创建WatcherHolder实例,其实是对AlarmRulesWatcher实例的重新封装,格式改key为alarm.default.alarm-settingsWatcherHolderholder=newWatcherHolder(watcher);if(register.containsKey(holder.getKey())){thrownewIllegalStateException("Duplicateregister,watcher="+watcher);}//每个不同的key对应不同的WatcherHolder实例,即不同的动态配置对应不同的处理方式。register.put(holder.getKey(),holder);}随后调用ConfigWatcherRegister抽象类的start方法:publicvoidstart(){isStarted=true;//同步动态配置configSync();LOGGER.info("引导同步后的当前配置。"+LINE_SEPARATOR+register.toString());//每隔一段时间异步执行动态配置的同步执行器syncPeriod,TimeUnit.SECONDS);}查看同步动态配置的configSync方法:voidconfigSync(){//读取所有注册的动态配置,包括告警配置。可选configTable=readConfig(register.keys());//如果未检测到配置更改,configTable可能为空。configTable.ifPresent(config->{config.getItems().forEach(item->{StringitemName=item.getName();//获取配置对应的WatcherHolder实例WatcherHolderholder=register.get(itemName);if(holder!=null){ConfigChangeWatcherwatcher=holder.getWatcher();StringnewItemValue=item.getValue();if(newItemValue==null){if(watcher.value()!=null){//如果新的configuration如果为null,则发送删除配置的消息类型watcher.notify(newConfigChangeWatcher.ConfigChangeEvent(null,ConfigChangeWatcher.EventType.DELETE));}else{//如果没有调用notify方法,则保留配置为空。}}else{if(!newItemValue.equals(watcher.value())){watcher.notify(newConfigChangeWatcher.ConfigChangeEvent(newItemValue,ConfigChangeWatcher.EventType.MODIFY));}else{//如果没有调用notify方法,则保持相同的配置。}}}else{LOGGER.warn("Config{}来自配置中心,不匹配任何watcher,忽略。",itemName);}});LOGGER.trace("同步后的当前配置。"+LINE_SEPARATOR+register.toString());});}注:本文以SkyWalking8.2.0版本为例,版本不同会有细微差异。