概要
此篇博客重点讲述SpringCloudAlibaba的nacos的客户端是怎么在启动的时候,把自己的服务注册到注册中心的。
综述
- SpringcloudAlibaba既然是SpringCloud项目,那么它必定遵循SpringCloud定义的规范,该规范包括一些注册服务,下线服务等。
- SpringCloudAlibaba又是一个SpringBoot项目,那么它肯定也遵循SpringBoot的规范,该规范包括自动装配的spring.factories
- SpringCloudAlibaba的启动必然是使用SpringBoot的自动装配的技术来实现它的自动启动,相对来说主要是SpringBoot的流程
流程图
可右键下载
步骤
一,maven仓库地址
项目中引入的是这个jar包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
二,查看对应的jar包
三,点开jar包,查看jar包的自动配置文件
四,看这个文件
发现了一堆的自动注册的类。我们现在要看的代码是服务自动注册的流程,下列代码最符合这个意思的是
NacosServiceRegistryAutoConfiguration
五,配置类的代码
-
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration
-
调用构造方法
public NacosAutoServiceRegistration(ServiceRegistry<Registration> serviceRegistry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
super(serviceRegistry, autoServiceRegistrationProperties);
this.registration = registration;
}
- 这个是调用父类的构造方法 org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration
protected AbstractAutoServiceRegistration(ServiceRegistry<R> serviceRegistry,
AutoServiceRegistrationProperties properties) {
this.serviceRegistry = serviceRegistry;
this.properties = properties;
}
-
顺便看看这个的关系图
-
有一个关键的实现,那就是ApplicationLIstener,它会在项目启动的时候调用,我们看看这个方法
-
它的父类实现了具体的方法,我们来看看方法具体
监听web容器启动完成之后发布的事件
@Override
@SuppressWarnings("deprecation")
public void onApplicationEvent(WebServerInitializedEvent event) {
bind(event);
}
- 看bind方法
@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();
}
- 看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);
}
}
- 看register方法
/**
* Register the local service with the {@link ServiceRegistry}.
*/
protected void register() {
this.serviceRegistry.register(getRegistration());
}
- com.alibaba.cloud.nacos.registry.NacosServiceRegistry#register
这个类就是在实例化的时候传入的类,那么当然是调用这个类来完成注册
@Override
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
NamingService namingService = namingService();
String serviceId = registration.getServiceId();
String group = nacosDiscoveryProperties.getGroup();
// 构建实例
Instance instance = getNacosInstanceFromRegistration(registration);
try {
// 注册实例
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);
// rethrow a RuntimeException if the registration is failed.
// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
rethrowRuntimeException(e);
}
}
- 看注册方法 com.alibaba.nacos.api.naming.NamingService#registerInstance
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
NamingUtils.checkInstanceIsLegal(instance);
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
if (instance.isEphemeral()) {
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
beatReactor.addBeatInfo(groupedServiceName, beatInfo);
}
serverProxy.registerService(groupedServiceName, groupName, instance);
}
- 看registerService方法
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}", namespaceId, serviceName,
instance);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort()));
params.put("weight", String.valueOf(instance.getWeight()));
params.put("enable", String.valueOf(instance.isEnabled()));
params.put("healthy", String.valueOf(instance.isHealthy()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
}
看到这里就不用往下继续看了,很明显,这里构建了一堆的参数。用来发送http网络请求。服务器会收到这个请求,把实例数据保存下来
版权声明:本文为qq_22986265原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。