服务发现与注册,是注册中心吗?
是。
但注册中心只是 各微服务治理方案中服务发现与注册的实现而已。
比如 eureka,nacos,zk等都是可以作为 dubbo与 spring cloud 的注册中心。
现在聊一下spring cloud 中 服务的注册与发现的抽象:
AbstractAutoServiceRegistration
这是一个抽象类。
- 注入。
nacos中
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosAutoServiceRegistration nacosAutoServiceRegistration(
NacosServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
这个类通过@Bean 注入到spring 容器中。
- 启动
AbstractAutoServiceRegistration 实现了ApplicationListener接口,监听了WebServerInitializedEvent事件。源码如下:
public void onApplicationEvent(WebServerInitializedEvent event) {
this.bind(event);
}
-->
public void bind(WebServerInitializedEvent event) {
ApplicationContext context = event.getApplicationContext();
if (!(context instanceof ConfigurableWebServerApplicationContext) || !"management".equals(((ConfigurableWebServerApplicationContext)context).getServerNamespace())) {
this.port.compareAndSet(0, event.getWebServer().getPort());
this.start();
}
}
-->
public void start() {
if (!this.isEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Discovery Lifecycle disabled. Not starting");
}
} else {
if (!this.running.get()) {
this.context.publishEvent(new InstancePreRegisteredEvent(this, this.getRegistration()));
this.register();
if (this.shouldRegisterManagement()) {
this.registerManagement();
}
this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));
this.running.compareAndSet(false, true);
}
}
}
- 注册
在上面的源码中。this.register() --> 就是服务的注册服务。
this.register()
-->this.serviceRegistry.register(this.getRegistration());
其中 serviceRegistry 的接口定义如下:
public interface ServiceRegistry<R extends Registration> {
void register(R registration);
void deregister(R registration);
void close();
void setStatus(R registration, String status);
<T> T getStatus(R registration);
}
该接口具体的实现在各个注册中心中。已nacos为例为:NacosServiceRegistry。各个注册中心的实现不一样,请查看注册中心源码。
4.发现。
服务发现以springcloudalibaba为例:
在springboot启动时,注入了一个配置类
DubboServiceDiscoveryAutoConfiguration其中有一个方法实现了对HeartbeatEvent事件的监听
-->
@EventListener(HeartbeatEvent.class)
public void onHeartbeatEvent(HeartbeatEvent event) {
...//省略
List<ServiceInstance> serviceInstances = getInstances(serviceName); ...//省略
}
-->该方法调用了spring cloud的统一服务类DscoveryClient类中的服务发现接口
private List<ServiceInstance> getInstances(String serviceName) {
return discoveryClient.getInstances(serviceName);
}
-->
假如配置的nacos为服务注册中心,那么实现类为 NacosDiscoveryClient。
那么 这个HeartbeatEvent事件由谁发布的呢?
在NacosDiscoveryClientConfiguration的配置类中,注入了一个配置类
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled",
matchIfMissing = true)
public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties,
ObjectProvider<TaskScheduler> taskScheduler) {
return new NacosWatch(nacosDiscoveryProperties, taskScheduler);
}
-->NacosWatch类中有一个方法
@Override
public void start() {
if (this.running.compareAndSet(false, true)) {
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
this::nacosServicesWatch, this.properties.getWatchDelay());
}
}
-->
public void nacosServicesWatch() {
// nacos doesn't support watch now , publish an event every 30 seconds.
this.publisher.publishEvent(
new HeartbeatEvent(this, nacosWatchIndex.getAndIncrement()));
}
这个类实现了SmartLifecycle接口(当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法))
因此,nacos的服务发现是在spring容器加载为所有bean之后,通过NacosWatch发布HeartbeatEvent 事件,DubboServiceDiscoveryAutoConfiguration中的中实现监听这个事件来完成的。
剧终!!!
参考:https://blog.csdn.net/qq_42651904/article/details/121876171