如果让你设计一个动态配置的功能,你会怎么做?注意是动态配置,不是配置中心。

先在大脑里面考虑3分钟,也许你有答案了。

对的,你肯定想的和下面一样:

 

nacos2.0架构 nacos架构原理_服务器

 

  

上图是需要人工发起通知的动态配置架构,实现很简单。

但我们为什么要人工操作两次呢,可不可以简化到一次?

对于上图只需要稍作调整,就能达到只需要一次修改配置文件操作。

 

nacos2.0架构 nacos架构原理_管理类_02

 

 

这样看起来简单多了。

采用定时任务,可以减少人工操作次数,但同时带来了一定的性能损耗。

回到nacos,它多采用的模型是定时任务来获取配置文件。

如果是一台机器,一个配置文件,上面的架构似乎完美胜任,如果将应用变成n个,机器n台,配置文件n个,

此时就会存在问题,人工操作不可能完成上面的工作,也容易出错。必须要自动化才能既保证效率提高,还

能保证不出错。

对此,只需要将上面的架构稍微改一改,就能满足需求。

 

nacos2.0架构 nacos架构原理_服务器_03

 

 

nacos就是以上架构,十分的简单。

现在来看下他是如何集成到SpringCloud里面取得。

先来了解SpringBoot/SpringCloud中几个关键类。

MapPropertySource<T>:这个是spring中属性配置的数据源,所有的配置文件都要转成这样的形式。
RefreshEvent:发送该事件,可以类似调用RefreshEndpoint#refresh,也就是通知spring刷新配置文件。
EnvironmentChangeEvent:发送该事件,会通知环境已经发生变化。
ContextRefresher:刷新管理类。
NacosContextRefresher:nacos配置上下文管理类。
RefreshScope:该注解会把bean加入到'refresh'的scope中。

ClientWorker:nacos配置中心客户端,会定时http请求服务器。
其通信图如下:

 

nacos2.0架构 nacos架构原理_配置文件_04

 

 

1.在nacos上修改配置。

2.nacos客户端中ClientWorker会每隔10ms异步读取一次配置中心文件md5值。

3.和本地md5值比较,有变化的从服务器拉取。

4.将文件保存/缓存到本地。

5.通知NacosContextRefresher配置文件有变化。

6.NacosContextRefresher判断是否需要更新配置。

7.发送事件通知ContextRefresher去更新。

8.这里是更新配置的关键步骤。

9.准备一份before配置,然后通过构建新的Environment的方式拿到新的配置, 接着比较变化,得到有变化的keys。

10.构建Environment时会去读取配置文件,文件优先读本地,如果本地没有通过Http请求服务商。

11.构建NacosPropertiesSource,并重新生成ConfigurationProperties对象。

12.通知RefreshScope去更新。

13.销毁scope='refresh'的bean。

14.通知bean容器去构建新的bean(懒加载)。

15.将属性(@Value注解)注入到新的bean。