spring cloud定义了以下几个类用于服务的注册、发现操作
- DiscoveryClient 接口代表服务发现常见的读取操作
public interface DiscoveryClient extends Ordered {
int DEFAULT_ORDER = 0;
String description();
// 根据服务id获取对应的服务列表
List<ServiceInstance> getInstances(String serviceId);
// 获取所有服务名称
List<String> getServices();
default void probe() {
this.getServices();
}
default int getOrder() {
return 0;
}
}
- EnableDiscoverClient 使用注解表示开启服务发现功能
- ServiceInstance 接口代表服务的一个实例
在DiscoveryClient的getInstances方法中可以看到返回的list范型为ServiceInstance 每一个ServiceInstance代表的就是一个服务实例的信息
public interface ServiceInstance {
default String getInstanceId() {
return null;
}
String getServiceId();
String getHost();
int getPort();
boolean isSecure();
URI getUri();
Map<String, String> getMetadata();
default String getScheme() {
return null;
}
}
- Registration接口 代表服务注册时需要用到的实例信息,通过源码可以看到该接口即成ServiceInstance接口,并且没有任何扩展实际上就是ServiceInstance 只不过代表的意义有所区别 。
既ServiceInstance代表在注册中心获取的实例信息 Registration代表服务注册时需要发送到注册中心的数据
public interface Registration extends ServiceInstance {
}
- 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);
}
- AutoServiceRegistration 是一个空接口代表服务的自动注册该接口有一个抽象的实现类AbstractAutoServiceRegistration 并且该抽象类实现了ApplicationListener接口 监听WebServerInitializedEvent事件,当事件被触发后AbstractAutoServiceRegistration调用ServiceRegistry.registry 进行服务的注册.
AbstractAutoServiceRegistration关键代码如下
public abstract class AbstractAutoServiceRegistration<R extends Registration>
implements AutoServiceRegistration, ApplicationContextAware, ApplicationListener<WebServerInitializedEvent> {
@Override
@SuppressWarnings("deprecation")
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);
}
}
protected void register() {
this.serviceRegistry.register(getRegistration());
}
以上的类是Spring cloud定义的模型,任何服务注册中心想与Spring Cloud进行整合都需要实现上面的接口扩展对应的实体类。例如:eureka、nacos等服务注册中心,下面看下nacos的实现方式
nacos对于以上模型的实现类如下:
- NacosDiscoveryClient实现DiscoveryClient
- NacosServiceInstance实现ServiceInstance
- NacosRegistration 实现Registration
- NacosServiceRegistry 实现ServiceRegistry
- NacosAutoServiceRegistration 继承AbstractAutoServiceRegistration
在Spring-cloud-starter-alibaba-nacos-discovery 项目的spring.factories文件中可以看到EnableAutoConfiguration对应的类中有一个NacosServiceRegistryAutoConfiguration类 springboot通过工厂加载机制加载该类用于配置nacos的服务自动注册,在该配置类中加载了NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration类
public class NacosServiceRegistryAutoConfiguration {
public NacosServiceRegistryAutoConfiguration() {
}
@Bean
public NacosServiceRegistry nacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosServiceRegistry(nacosDiscoveryProperties);
}
@Bean
@ConditionalOnBean({AutoServiceRegistrationProperties.class})
public NacosRegistration nacosRegistration(ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers, NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) {
return new NacosRegistration((List)registrationCustomizers.getIfAvailable(), nacosDiscoveryProperties, context);
}
@Bean
@ConditionalOnBean({AutoServiceRegistrationProperties.class})
public NacosAutoServiceRegistration nacosAutoServiceRegistration(NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);
}
}
上面说过AbstractAutoServiceRegistration实现了ApplicationListener监听WebServerInitializedEvent事件,所以在该事件触发时NacosAutoServiceRegistration自动开始实现对nacos服务注册中心进行注册
NacosDiscoveryClientConfiguration类 springboot通过工厂加载机制加载该类用于配置nacos的服务自动注册,在该配置类中加载了nacosDiscoveryClient类实现服务发现的常见读取操作