1. 服务注册
服务注册的核心类如下
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class,
NacosDiscoveryAutoConfiguration.class })
public class NacosServiceRegistryAutoConfiguration {
// ① 创建 Nacos 服务注册中心
@Bean
public NacosServiceRegistry nacosServiceRegistry(
NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosServiceRegistry(nacosDiscoveryProperties);
}
// ② 创建 Nacos 服务注册的实例
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosRegistration nacosRegistration(
ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,
NacosDiscoveryProperties nacosDiscoveryProperties,
ApplicationContext context) {
return new NacosRegistration(registrationCustomizers.getIfAvailable(),
nacosDiscoveryProperties, context);
}
// ③ 创建 Nacos 自动服务注册实现类
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosAutoServiceRegistration nacosAutoServiceRegistration(
NacosServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
}
注册过程
创建 Nacos 服务注册中心
com.alibaba.cloud.nacos.registry.NacosServiceRegistry
;创建 Nacos 服务注册的实例
com.alibaba.cloud.nacos.registry.NacosRegistration
,判断条件为是否存在 Beanorg.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties
;创建 Nacos 自动服务注册工具类
com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration
,判断条件同上;-
NacosAutoServiceRegistration 会获取 NacosRegistration 并注册到 NacosServiceRegistry
public class NacosAutoServiceRegistration extends AbstractAutoServiceRegistration<Registration> { ... private NacosRegistration registration; ... @Override protected void register() { if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { log.debug("Registration disabled."); return; } if (this.registration.getPort() < 0) { this.registration.setPort(getPort().get()); } super.register(); } ... }
2. 服务发现
服务发现核心代码:
public class NacosDiscoveryClient implements DiscoveryClient {
private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class);
/**
* Nacos Discovery Client Description.
*/
public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";
private NacosServiceDiscovery serviceDiscovery;
public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
this.serviceDiscovery = nacosServiceDiscovery;
}
@Override
public String description() {
return DESCRIPTION;
}
@Override
public List<ServiceInstance> getInstances(String serviceId) {
try {
return serviceDiscovery.getInstances(serviceId);
}
catch (Exception e) {
throw new RuntimeException(
"Can not get hosts from nacos server. serviceId: " + serviceId, e);
}
}
@Override
public List<String> getServices() {
try {
return serviceDiscovery.getServices();
}
catch (Exception e) {
log.error("get service name from nacos server fail,", e);
return Collections.emptyList();
}
}
}
public class NacosServiceDiscovery {
...
public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
String group = discoveryProperties.getGroup();
List<Instance> instances = namingService().selectInstances(serviceId, group,
true);
return hostToServiceInstanceList(instances, serviceId);
}
...
private NamingService namingService() {
return nacosServiceManager.getNamingService(discoveryProperties.getNacosProperties());
}
}
从以上代码可以看到,NacosDiscoveryClient
实现了 org.springframework.cloud.client.discovery.DiscoveryClient
接口,其 #getInstances()
方法从 NacosServiceDiscovery#getInstance()
获取对应的服务实例信息。
NacosServiceDiscovery
从 NacosServiceManager
获取 NameService
,然后通过 NamingService#selectInstances()
获取实例信息,并转换为 org.springframework.cloud.client.ServiceInstance
类型返回给 Spring 管理。
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
@ConditionalOnBlockingDiscoveryEnabled
@ConditionalOnNacosDiscoveryEnabled
@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class,
CommonsClientAutoConfiguration.class })
@AutoConfigureAfter(NacosDiscoveryAutoConfiguration.class)
public class NacosDiscoveryClientConfiguration {
@Bean
public DiscoveryClient nacosDiscoveryClient(
NacosServiceDiscovery nacosServiceDiscovery) {
return new NacosDiscoveryClient(nacosServiceDiscovery);
}
...
}
从上面的代码可以看到,NacosDiscoveryClientConfiguration
注册了 NacosDiscoveryClient
。
发现过程
-
NacosDiscoveryClient
实现了org.springframework.cloud.client.discovery.DiscoveryClient
接口; - 其
getInstances
方法从NacosServiceDiscovery#getInstance()
获取对应的服务实例信息; -
NacosServiceDiscovery
从discoveryProperties
获取NamingService
,然后通过NamingService.selectInstances
获取实例信息,然后转换为org.springframework.cloud.client.ServiceInstance
类型; -
getServices
方法通过NamingService.getServicesOfServer
获取services
信息。
3. 自动装配
从以上代码可以看出,Nacos 服务注册与发现均是通过注解的方式进行判断是否存在对应的配置类,是否配置了允许等条件动态的创建对应的 Bean。
参考文档