死磕源码系列【consul配置中心监视器类ConfigWatch动态刷新配置】

consul作为配置中心时可以开启动态刷新配置的功能,其实现类是通过ConfigWatch来实现;

监视器类相关属性配置
spring:
  cloud:
    consul:
      config:
        watch:
          # 是否开启配置中心配置变动,默认:true
          enabled: true
          # 监控的固定延迟值,即一次执行完成到下一次执行开始之间的间隔,默认:1000毫秒
          delay: 1000
          # 等待(或阻塞)监视查询的秒数,默认:55秒,需要小于60
          wait-time: 55

此处要说明一下wait-time属性,此属性是设置调用consul的接口方法时会阻塞指定的时间,如果在阻塞过程中有配置修改则立马返回,否则要等到阻塞时间结束,delay属性指的是在上次调用接口结束之后多久开始下一次调度;

1.ConfigWatch定时任务配置方法
	@Override
	public void start() {
		if (this.running.compareAndSet(false, true)) {
			this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::watchConfigKeyValues,
					this.properties.getWatch().getDelay());
		}
	}

指定一个固定的线程池,每次在上次任务执行完成后间隔指定的时间执行下次任务;

2.watchConfigKeyValues监视器任务方法
	@Timed("consul.watch-config-keys")
	public void watchConfigKeyValues() {
		if (!this.running.get()) {
			return;
		}
		for (String context : this.consulIndexes.keySet()) {
			  ...
        //通过API调度获取配置中心配置信息,接口阻塞指定的超时时间,默认是:55s
				Response<List<GetValue>> response = this.consul.getKVValues(context, aclToken,
						new QueryParams(this.properties.getWatch().getWaitTime(), currentIndex));

				// if response.value == null, response was a 404, otherwise it was a
				// 200, reducing churn if there wasn't anything
				if (response.getValue() != null && !response.getValue().isEmpty()) {
          // 获取配置中心的新版本
					Long newIndex = response.getConsulIndex();

					if (newIndex != null && !newIndex.equals(currentIndex)) {
						// 判定新版本和老版本是否一样,不同则发布事件刷新
						if (!this.consulIndexes.containsValue(newIndex) && !currentIndex.equals(-1L)) {
							if (log.isTraceEnabled()) {
								log.trace("Context " + context + " has new index " + newIndex);
							}
							RefreshEventData data = new RefreshEventData(context, currentIndex, newIndex);
              //发布刷新本地配置事件
							this.publisher.publishEvent(new RefreshEvent(this, data, data.toString()));
						}
						else if (log.isTraceEnabled()) {
							log.trace("Event for index already published for context " + context);
						}
						this.consulIndexes.put(context, newIndex);
					}
				...
	}

上述监视器方法监测到配置变化会发布RefreshEvent事件,该事件会被RefreshEventListener监听器监听

3.RefreshEventListener监听器
public class RefreshEventListener implements SmartApplicationListener {

	private static Log log = LogFactory.getLog(RefreshEventListener.class);

	private ContextRefresher refresh;

	private AtomicBoolean ready = new AtomicBoolean(false);

	public RefreshEventListener(ContextRefresher refresh) {
		this.refresh = refresh;
	}

	@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
		return ApplicationReadyEvent.class.isAssignableFrom(eventType)
				|| RefreshEvent.class.isAssignableFrom(eventType);
	}

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ApplicationReadyEvent) {
			handle((ApplicationReadyEvent) event);
		}
		else if (event instanceof RefreshEvent) {
			handle((RefreshEvent) event);
		}
	}

	public void handle(ApplicationReadyEvent event) {
		this.ready.compareAndSet(false, true);
	}

	public void handle(RefreshEvent event) {
		if (this.ready.get()) { // don't handle events before app is ready
			log.debug("Event received " + event.getEventDesc());
      //调用ContextRefresher刷新配置方法
			Set<String> keys = this.refresh.refresh();
			log.info("Refresh keys changed: " + keys);
		}
	}

}

GitHub地址:https://github.com/mingyang66/EmilyGateway

根据引用和引用的内容,spring cloud consul是通过依赖spring-cloud-consul-discovery包来实现在consul上注册服务的。而在注册服务时,需要创建一个consulapi.Client来连接到consul服务器,并使用consul.NewClient来创建一个consul的客户端。接下来,需要创建一个consulapi.AgentServiceRegistration对象来配置注册的服务信息,例如服务的ID、名称、标签、端口、地址等。然后,使用consul.NewRegistrar将服务注册到consul中。最后,在服务关闭时,需要调用Deregister方法来取消注册。这样就完成了在consul上注册服务的过程。 关于consul配置中心源码分析,根据提供的引用内容,无法直接得出详细源码分析的结论。因为这里提供的是关于服务注册的部分代码片段,没有涉及到完整的配置中心源码。如果你有关于具体的配置中心源码分析的问题,可以提供更多相关的引用内容,以便进行更详细的分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [.NetCore 为什么选择使用Nacos服务治理](https://download.csdn.net/download/X252618759/83482732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [spring cloud consul服务注册源码分析](https://blog.csdn.net/qq_41645636/article/details/130100232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [go-kit-consul client服务发现源码分析](https://blog.csdn.net/csdnfanguyinheng/article/details/125622540)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值