Nacos - 启动中提到了注册的入口,这里就讲一下注册的细节。
Tomcat启动成功后,会调用AbstractAutoServiceRegistration的onApplicationEvent方法,他会继续调用AbstractAutoServiceRegistration#bind。
AbstractAutoServiceRegistration#bind
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();
}
AbstractAutoServiceRegistration#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()) {
// 发布InstancePreRegisteredEvent事件
this.context.publishEvent(
new InstancePreRegisteredEvent(this, getRegistration()));
// 注册
register();
if (shouldRegisterManagement()) {
// 注册registerManagement
registerManagement();
}
// 发布InstanceRegisteredEvent事件
this.context.publishEvent(
new InstanceRegisteredEvent<>(this, getConfiguration()));
// 设置状态为启动
this.running.compareAndSet(false, true);
}
}
NacosAutoServiceRegistration#register
protected void register() {
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
log.debug("Registration disabled.");
return;
}
// 小于0重新设置端口
if (this.registration.getPort() < 0) {
this.registration.setPort(getPort().get());
}
super.register();
}
AbstractAutoServiceRegistration#register
registration的注入在启动的时候已经说过了。
protected void register() {
this.serviceRegistry.register(getRegistration());
}
NacosServiceRegistry#register
封装好Instance后,调用NacosNamingService的registerInstance方法注册。Nacos - NacosNamingService初始化以及几个其他定时任务已经讲过了。
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
// 获取NacosNamingService
NamingService namingService = namingService();
// 获取serviceId
String serviceId = registration.getServiceId();
String group = nacosDiscoveryProperties.getGroup();
// 获取Instance,一些信息从registration读取,一些从nacosDiscoveryProperties读取
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);
}
}
NacosNamingService#registerInstance
封装心跳信息、开启定时任务续约以及调用serverProxy注册,这个url是/nacos/v1/ns/instance。
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
if (instance.isEphemeral()) {
// 封装心跳信息
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
// 开启定时任务续约
beatReactor.addBeatInfo(groupedServiceName, beatInfo);
}
serverProxy.registerService(groupedServiceName, groupName, instance);
}