Nacos Config动态刷新原理

本文探讨了微服务环境下配置管理面临的挑战,如配置数量增多、环境区分困难及动态更新问题。配置中心的引入,如Apollo、Diamond和Nacos等,解决了这些问题。Nacos采用客户端拉取的LongPolling方式,避免了Push的长连接和Pull的频繁请求。长轮询在保证数据时效性的同时降低了无效请求的压力。
摘要由CSDN通过智能技术生成

微服务中的配置

在我们的微服务的运行环境中,每一个微服务往往不会只有一套环境,在企业中往往存在至少三套运行环境:开发测试生产

在这套微服务系统中,会存在三个问题:

  1. 配置文件的数量会随着微服务的增多而增多
  2. 单个配置文件无法区分多个运行环境
  3. 配置文件无法动态更新,修改配置文件后需要重启对应的微服务

当我们引入配置中心,它能解决什么问题?

  1. 统一的配置文件的管理
  2. 提供统一的服务标准接口,服务根据标准接口拉去对应的配置,也就是常见pull/push模型
  3. 支持配置文件动态更新到对应的服务

业界常见的配置中心:

  • 携程开源 Apollp(阿波罗)
  • 阿里 Diamond
  • 百度 DisConfig
  • SpringCloud Config
  • Nacos

推拉模型

Push

表示服务端主动将数据变更推送更新到客户端
如下图所示,如果有多个客户端时,服务端和客户端需要保持长链接,并且需要存放多个客户端的连接映射地址,还需要保持客户端与服务端的心跳机制

Pull

客户端主动去服务端拉取数据
由于为了保证数据的时效性,客户端需要频繁去拉去服务端的数据,而在服务端长时间未更新的情况下,存在许多无效的Pull

Nacos动态刷新原理

抛出一个问题,Nacos做配置中心的时候,配置数据的交互模式是有服务端push推送的,还是客户端pull拉取的?

Nacos客户端发送一个请求连接到服务端,然后服务端中会有一个29.5+0.5s的一个hold期,然后服务端会将此次请求放入到allSubs队列中等待,触发服务端返回结果的情况只有两种,第一种是时间等待了29.5秒,配置未发生改变,则返回未发生改变的配置;第二种是操作Nacos Dashboard或者API对配置文件发生一次变更,此时会触发配置变更的事件,发送一条LocalDataEvent消息,此时服务端监听到消息,然后遍历allSubs队列,根据对应的groupId找到配置变更的这条ClientLongPolling任务,并且通过连接返回给客户端

Nacos动态刷新避免了服务端对客户端进行push操作时需要保持双方的心跳连接,同样也避免了客户端对服务端进行pull操作时数据的时效性问题,不必频繁去拉去服务端的数据

通过上面原理的初步了解,显而易见,答案是:客户端主动拉取的,通长轮询的方式(Long Polling)的方式来获取配置数据

短轮询

不管服务端的配置是否发生变化,不停发起请求去获取配置,比如支付订单场景中前端JS不断轮询订单支付的状态

这样的坏处显而易见,由于配置并不会频繁发生变更,如果是一直发请求,一定会对服务端造成很大的压力。还会造成数据推送的延迟,比如每10秒请求一次配置,如果在第11秒的时候配置更新,那么推送将会延迟9秒,等待下一次请求

这就是短轮询,为了解决短轮询的问题,有了长轮询的方案

长轮询

长轮询不是什么新技术,它其实就是由服务端控制响应客户端请求结果的返回时间,来减少客户端无效请求的一种优化手段,其实对于客户端来说,短轮询的使用并没有本质上的区别

客户端发起请求后,服务端不会立即返回请求结果,而是将请求hold挂起一段时间,如果此时间段内配置数据发生变更,则立即响应客户端,若一直无变更则等到指定超时时间后响应给客户端结果,客户端重新发起长链接

Nacos实现配置的动态刷新主要依靠客户端的长轮询和事件发布机制。具体步骤如下: 1. 客户端通过长轮询方式向Nacos服务端发送请求,获取最新的配置信息。 2. Nacos服务端会监测配置的变化,并在配置发生变化时将最新的配置信息返回给客户端。 3. 客户端接收到最新的配置信息后,会通过Spring的ApplicationContext.publishEvent()方法发布事件。 4. 通过事件发布机制,客户端可以通知相关的组件或模块进行配置的动态刷新,以达到热部署的效果。 下面是一个示例代码,演示了如何在Nacos中实现配置的动态刷新: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component; @Component @RefreshScope public class ConfigListener implements ApplicationEventPublisherAware { private ApplicationEventPublisher eventPublisher; @Value("${config.key}") private String configValue; @Override public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void refreshConfig() { // 根据最新的配置信息进行相应的操作 System.out.println("Config value: " + configValue); // 发布事件,通知其他组件进行配置的动态刷新 eventPublisher.publishEvent(new ConfigRefreshEvent()); } } ``` 在上述示例中,通过@RefreshScope注解标注了ConfigListener类,表示该类中的配置信息可以动态刷新。当配置发生变化时,会自动更新configValue的值,并通过事件发布机制通知其他组件进行配置的动态刷新
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值