版本说明
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>2.2.0.RELEASE</version>
1、nacos服务注册客户端使用
1.1导入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
1.2启动类上加注解@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class,args);
}
}
3、注册中心服务端的配置信息
2、spring.factories文件
springboot应用在启动时会加载类路径下META-INF/spring.factories文件,将key为
org.springframework.boot.autoconfigure.EnableAutoConfiguration
对应的value加载到spring容器中。
在spring-cloud-alibaba-nacos-discovery模块类路径下META-INF/spring.factories文件中,导入了 NacosDiscoveryAutoConfiguration、NacosServiceRegistryAutoConfiguration、RibbonNacosAutoConfiguration等配置类
2.1 NacosDiscoveryAutoConfiguration 读取properties配置文件
public class NacosDiscoveryAutoConfiguration {
//注入spring.cloud.nacos.discovery配置
@Bean
@ConditionalOnMissingBean
public NacosDiscoveryProperties nacosProperties() {
return new NacosDiscoveryProperties();
}
//nacos服务发现客户端
@Bean
@ConditionalOnMissingBean
public NacosServiceDiscovery nacosServiceDiscovery(
NacosDiscoveryProperties discoveryProperties) {
return new NacosServiceDiscovery(discoveryProperties);
}
}
2.2 nacos服务注册客户端启动流程
NacosServiceRegistryAutoConfiguration
public class NacosServiceRegistryAutoConfiguration {
//nacos服务注册
@Bean
public NacosServiceRegistry nacosServiceRegistry(
NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosServiceRegistry(nacosDiscoveryProperties);
}
//封装服务注册配置信息和上下文
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosRegistration nacosRegistration(
NacosDiscoveryProperties nacosDiscoveryProperties,
ApplicationContext context) {
return new NacosRegistration(nacosDiscoveryProperties, context);
}
//构造器传入的就是上面注入的NacosServiceRegistry
//整合springcloud common,监听WebServerInitializedEvent事件
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosAutoServiceRegistration nacosAutoServiceRegistration(
NacosServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
}
NacosAutoServiceRegistration
public abstract class AbstractAutoServiceRegistration<R extends Registration> implements AutoServiceRegistration, ApplicationContextAware, 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()));
//注册 NacosAutoServiceRegistration重写了register方法
this.register();
if (this.shouldRegisterManagement()) {
this.registerManagement();
}
this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));
this.running.compareAndSet(false, true);
}
}
}
}
//父类AbstractAutoServiceRegistration实现了ApplicationListener接口,监听WebServerInitializedEvent
public class NacosAutoServiceRegistration
extends AbstractAutoServiceRegistration<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());
}
//最后调用到NacosServiceRegistry.register
super.register();
}
}
public class NacosServiceRegistry implements ServiceRegistry<Registration> {
//服务注册和服务发现的顶层接口
private final NamingService namingService;
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
//service
String serviceId = registration.getServiceId();
//group
String group = nacosDiscoveryProperties.getGroup();
Instance instance = getNacosInstanceFromRegistration(registration);
try {
//服务注册 进入到nacos的源码
namingService.registerInstance(serviceId, group, instance);
log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
instance.getIp(), instance.getPort());
}
catch (Exception e) {
log.error("nacos registry, {} register failed...{},", serviceId,
registration.toString(), e);
rethrowRuntimeException(e);
}
}
}
2.3 nacos整合ribbon
RibbonNacosAutoConfiguration是nacos整合服务注册客户端整合ribbon的配置类,指定了RibbonClients的配置类为NacosRibbonClientConfiguration
@AutoConfigureAfter(RibbonAutoConfiguration.class)
@RibbonClients(defaultConfiguration = NacosRibbonClientConfiguration.class)
public class RibbonNacosAutoConfiguration {
}
public class NacosRibbonClientConfiguration {
@Autowired
private PropertiesFactory propertiesFactory;
//实现ribbon的ServerList组件,ServerList用来获取服务的地址信息
@Bean
@ConditionalOnMissingBean
public ServerList<?> ribbonServerList(IClientConfig config,
NacosDiscoveryProperties nacosDiscoveryProperties) {
if (this.propertiesFactory.isSet(ServerList.class, config.getClientName())) {
ServerList serverList = this.propertiesFactory.get(ServerList.class, config,
config.getClientName());
return serverList;
}
//基于NamingService做服务发现
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
serverList.initWithNiwsConfig(config);
return serverList;
}
}
注意:nacos注册中心自动配置,客户端只是将自己注册到注册中心,服务发现需要有服务调用的时候,借助于ribbon的ServerList组件,实现基于nacos的服务发现(从注册中心获取服务信息)