本文基于nacos-2.0.3版本
nacos服务端源码是使用spring boot编写的,初看源码,完全找不到头绪,不知道从哪看起。于是我改变了思路,从客户端开始看,然后从客户端调用的服务逐步深入到服务端。那么本文就来介绍一下客户端是如何从服务端拉取配置。
文章目录
- 一、注解@EnableNacosConfig
- 1、找到服务器地址信息
- 2、创建ConfigService对象
- 3、创建与服务器的连接
一、注解@EnableNacosConfig
要想使用nacos,客户端必须配置注解@EnableNacosConfig。
一般的使用EnableNacosConfig指定服务端的地址,比如:
该注解引入了一个非常重要的类:NacosConfigBeanDefinitionRegistrar。下面看一下这个类registerBeanDefinitions()方法。
NacosPropertySourcePostProcessor类的主要作用是:
- 找到服务器地址信息;
- 创建ConfigService对象
- 创建与服务器的连接
下面分别介绍这三个作用是如何实现的。
1、找到服务器地址信息
首先nacos遍历spring容器中所有的beanDefinition,从beanDefinition里面查找注解@NacosPropertySources或者@NacosPropertySource。
注解NacosPropertySource用于设置dataId和groupId,这两个值指定了配置在服务器上位置
nacos使用如下代码从注解里面找到dataId和groupId:
之后调用ConfigFactory.createConfigService()方法创建ConfigService对象。
createConfigService()方法通过反射调用了NacosConfigService的构造方法。
2、创建ConfigService对象
ConfigService提供了查看、删除、增加服务端配置的方法,并且还可以创建监听服务端配置的监听器。ConfigService相当于客户端与服务端之间的接口,通过它可以方便的控制服务端的配置数据。
我们可以通过@NacosInjected直接在程序中自动注入ConfigService对象。nacos内部也是通过ConfigService完成对服务端配置数据的增删改查。
下面介绍ConfigService的构造方法:
创建ClientWorker对象时,会创建一个定时任务,定时任务执行checkConfigInfo(),该方法的作用是检查服务配置是否发生变化,如果发生变化就更改本地缓存,同时发布事件,通知响应的对象更改其属性值,定时任务的代码如下:
配置定时更改的原理以后文章做介绍。
3、创建与服务器的连接
创建完ConfigService对象之后,nacos便可以通过ConfigService访问服务器读取dataId和groupId下的配置数据,那么这就需要建立与服务器之间的连接了。
连接的建立并且读取配置是通过ClientWorker.getServerConfig()完成的,下面只展示了ClientWorker.getServerConfig()方法的关键代码:
上面代码使用了MetricsHttpAgent.httpGet()方法,MetricsHttpAgent底层调用了ServerHttpAgent.httpGet()方法:
httpGet()方法的上述代码在一个循环里面,只要没有超过超时时间,它可以重试多次。
默认情况下,nacos使用jdk的URLConnection创建与服务端的连接,并且使用HTTP协议将请求发送到服务器。为了后面分析服务器行为方便,这里需要指出客户端请求的连接:
ConfigService找到了配置数据之后,nacos将这些数据组装到NacosPropertySource对象中,一个(dataId,groupId)对应一个NacosPropertySource对象。之后nacos将这些对象添加到spring的ConfigurableEnvironment对象的propertySources属性中,这样在应用程序中就可以像使用本地配置一样使用服务器上的配置数据了,包括占位符也可以直接处理。
如果在NacosPropertySource里面配置自动刷新,还会创建定时任务,这个在后面的文章中介绍。