Naocs
NacosServiceRegistryAutoConfiguration : 服务注册入口类
NacosAutoServiceRegistration : 自动注册服务流程
NacosServiceRegistry : 服务注册实现类
NacosRegistration : 服务注册实体,包含注册服务所需要的信息
NacosNamingMaintainService : 服务治理类(service)
NacosNamingService : 服务实例(instance)
NamingProxy : 网络代理类
NacosRegistrationCustomizer : 2020.9新版本中加入,用于向NacosRegistration中注入配置
CacheData : 维护配置项和其下注册的所有监听器的实例
BeatInfo : 心跳包信息
NacosDiscoveryAutoConfiguration: 服务发现入口
NacosDiscoveryProperties : 服务注册,发现相关的配置类
NacosServiceDiscovery : 服务发现的实现过程,为NacosDiscovery模块提供nacos上的service和instance信息.
NacosDiscoveryClientConfiguration :
NacosServiceInstance : 服务实例(instance)实体信息,只在服务发现模块使用
NacosDiscoveryClient : 服务信息提供类,提供getInstances和getServices方法
EventDispatcher : 当instances信息更新时,给监听者们发布事件消息.
NacosWatch : 监听EventDispatcher发布的消息,并同步到NacosDiscoveryProperties的元数据中
配置管理
服务注册
- 服务注册的入口类是NacosServiceRegistryAutoConfiguration,这里定义了三个重要的bean :NacosServiceRegistry,NacosRegistration,NacosAutoServiceRegistration
- 如果项目集成了spring-cloud-starter-alibaba-nacos-discovery,服务启动后默认是自动注册的。如果想看自动注册的过程,可以从NacosAutoServiceRegistration开始着手
- NacosServiceRegistry : 提供了register()方法给NacosAutoServiceRegistration进行服务注册.依赖NacosNamingService
- NacosRegistration : 服务注册实体,包含注册服务所需要的信息.提供了customize()方法给用户注入配置.
- NacosRegistrationCustomizer : 方便用户自定义 NacosRegistrationCustomizer 实现,向 NacosRegistration 中注入配置
- NacosDiscoveryProperties : 服务注册相关的配置类,读取application.yml里以spring.cloud.nacos.discovery为前缀的配置项
- NacosNamingMaintainService : 服务治理类(service),包含在nacos上创建服务,查询服务,删除服务等功能.通过调用关系可以发现该类是在NacosServiceRegistry的setStatus()方法(控制instance上线或下线)中被创建的,也就是nacos的服务是懒加载的,当需要对实例进行上线下线时,才会去获取对应的service,如果service不存在才会创建.而setStauts()是在ServiceRegistryEndpoint中被调用(spring cloud的类)
- NacosNamingService : 服务实例(instance)管理,包括把实例注册到服务上,订阅/取消订阅服务等功能.
- NamingProxy : 发起http请求的方法,基本上对于nacos服务器的所有网络请求都需要调用这里的callServer()
服务注册主流程 :
/**
*NacosAutoServiceRegistration
* Register the local service with the {@link ServiceRegistry}.
*/
protected void register() {
this.serviceRegistry.register(getRegistration());
}
/**
* NacosServiceRegistry
*/
public void register(Registration registration) {
namingService.registerInstance(serviceId, group, instance);
}
/**
* NacosNamingService
*/
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
serverProxy.registerService(groupedServiceName, groupName, instance); }
NacosAutoServiceRegistration中有两个事件监听器.
一个是onNacosDiscoveryInfoChangedEvent().当监听到NacosDiscoveryProperties的配置信息改变时就会重新注册.
@EventListener
public void onNacosDiscoveryInfoChangedEvent(NacosDiscoveryInfoChangedEvent event) {
restart();
}
private void restart() {
this.stop();
this.start();
}
另一个是在父类AbstractAutoServiceRegistration中定义的事件监听器,这是因为实现了ApplicationListener接口(需要先了解spring boot的事件监听机制).直接看onApplicationEvent()即可.
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
bind(event);
}
@Deprecated
public void bind(WebServerInitializedEvent event) {
ApplicationContext context = event.getApplicationContext();
if (context instanceof ConfigurableWebServerApplicationContext) {
if ("management".equals(((ConfigurableWebServerApplicationContext) context)
.getServerNamespace())) {
return;
}
}
this.port.compareAndSet(0, event.getWebServer().getPort());
this.start();
}
public void start() {
if (!isEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Discovery Lifecycle disabled. Not starting");
}
return;
}
// only initialize if nonSecurePort is greater than 0 and it isn't already running
// because of containerPortInitializer below
if (!this.running.get()) {
this.context.publishEvent(
new InstancePreRegisteredEvent(this, getRegistration()));
register();
if (shouldRegisterManagement()) {
registerManagement();
}
this.context.publishEvent(
new InstanceRegisteredEvent<>(this, getConfiguration()));
this.running.compareAndSet(false, true);
}
}
可以看到,服务注册是在WebServer启动完毕之后调用的.
此外,spring boot和nacos大量使用了**事件发布(ApplicationContext.publishEvent()) -> 事件监听(@EventListener) ) **的模式来控制各流程的执行顺序,这个特性需要好好掌握.
Spring 在实现的时候,通过设计模式(装饰),实现流程,又把关键部分丢给开发自己实现,提高了拓展性,然后巧妙的结合了观察者模式(变种),在合适的时间注册服务.
服务发现
- NacosDiscoveryAutoConfiguration : 服务发现的入口,包含NacosDiscoveryProperties和NacosServiceDiscovery两个bean.该类上有两个注解 : @ConditionalOnDiscoveryEnabled和@ConditionalOnNacosDiscoveryEnabled(都引入了@ConditionalOnProperty),也就是当配置项"spring.cloud.discovery.enabled"和"spring.cloud.nacos.discovery.enabled"都为true时才进行自动装配.由于这里设置了matchIfMissing = true,缺省值是true,所以默认是自动装配,不需要填写相关配置.也就是引入了nacos的相关包之后服务发现就自动开启了,不需要在Application类加上@EnableDiscoveryClient注解.
- @EnableDiscoveryClient原先是用于自动启用服务注册功能,以便其他服务发现本服务.在Spring的官方文档中已经声明**@EnableDiscoveryClient不是必须的了(从Spring Cloud Edgware开始),所有DiscoveryClient类型的bean都会自动注册**.
- NacosDiscoveryProperties : 是nacos的配置类,虽然从名字上看只属于服务发现这一模块,但实际上服务发现的配置也是由该类提供.负责读取并提供"spring.cloud.nacos.discovery"前缀的配置.overrideFromEnv()方法负责注入配置属性.此外,enrichNacosDiscoveryProperties()允许用户在配置文件里自定义额外的nacos配置.
- @PostConstruct : 上面这个类的init()方法里面用到,作用是当该类的依赖注入完成后,且该类被投入使用前,执行包含该注解的方法.作用类似于构造方法/构造代码块,目的是完成该类的初始化工作,之后才能服务于其他类.
- NacosServiceInstance : 服务实例(instance)实体信息,只在服务发现模块使用.
- NacosServiceDiscovery : 服务发现实现类,包含服务发现的过程,为NacosDiscovery模块提供nacos上的service和instance信息,并实现instance向serviceInstance的转换.依赖NacosServiceManager提供的namingService.这里需要注意的是虽然可以直接从NacosServiceManager得到服务信息,但是用户直接依赖的是NacosServiceDiscovery而不是NacosServiceManager,这样的设计的依据可能是单一职责原则,NacosServiceManager负责管理service,而对外提供服务的职责由NacosServiceDiscovery承担.
- NacosDiscoveryClientConfiguration : 加载NacosServiceDiscovery和NacosWatch两个bean.
- NacosDiscoveryClient : 服务信息提供类,仅对外提供NacosServiceDiscovery的getInstances和getServices方法(职责划分得很细嘛).也就是说nacos组件外想获取服务和实例信息的话都应该通过这个类获取.
- NacosWatch: 负责监听EventDispatcher中发布的instances更新事件,并同步到NacosDiscoveryProperties的元数据中.
Feign
FeignClientsRegistrar : 注册实现类
@EnableFeignClients
@EnableDiscoveryClient
@FeignClient