网站建设qinnet,html制作音乐网站代码,查询企业信息的官方网站,男做直播网站好spring-cloud-alibaba-nacos-discovery 老版本中如何调用nacos的 1. 整体结构#xff1a; 2. 思考: 如果你来做#xff0c;如何做client 向server注册服务#xff1a; 1.2.1 读yml#xff0c;或本地文件找到服务器地址#xff0c;以及其他配置 1.2.2 向server注册服务 1.2…spring-cloud-alibaba-nacos-discovery 老版本中如何调用nacos的 1. 整体结构 2. 思考: 如果你来做如何做client 向server注册服务 1.2.1 读yml或本地文件找到服务器地址以及其他配置 1.2.2 向server注册服务 1.2.3 定期发送心跳
3. 源码跟踪 3.1查看spring 自动装配 spring.factories 3.2 截图 3.3 查看NacosDiscoveryAutoConfiguration类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.alibaba.cloud.nacos;import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import com.alibaba.cloud.nacos.registry.NacosRegistration;
import com.alibaba.cloud.nacos.registry.NacosServiceRegistry;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
EnableConfigurationProperties
ConditionalOnNacosDiscoveryEnabled
ConditionalOnClass(name {org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent}
)
ConditionalOnProperty(value {spring.cloud.service-registry.auto-registration.enabled},matchIfMissing true
)
AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class})
public class NacosDiscoveryAutoConfiguration {public NacosDiscoveryAutoConfiguration() {}Beanpublic NacosServiceRegistry nacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {return new NacosServiceRegistry(nacosDiscoveryProperties);}BeanConditionalOnBean({AutoServiceRegistrationProperties.class})public NacosRegistration nacosRegistration(NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) {return new NacosRegistration(nacosDiscoveryProperties, context);}BeanConditionalOnBean({AutoServiceRegistrationProperties.class})public NacosAutoServiceRegistration nacosAutoServiceRegistration(NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);}
}3.3.1 注 可看出重点是三个Bean 注解的方法三个对象放入spring 进入管理我们需要依次查看三个对象这里就不一一查看了重点是NacosAutoServiceRegistration.class 。或者说入口是在NacosAutoServiceRegistration 然后再看另外两个对象 3.4. NacosAutoServiceRegistration 3.4.1 源码
public class NacosAutoServiceRegistration extends AbstractAutoServiceRegistrationRegistration {private static final Logger log LoggerFactory.getLogger(NacosAutoServiceRegistration.class);private NacosRegistration registration;public NacosAutoServiceRegistration(ServiceRegistryRegistration serviceRegistry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {super(serviceRegistry, autoServiceRegistrationProperties);this.registration registration;}/** deprecated */Deprecatedpublic void setPort(int port) {this.getPort().set(port);}protected NacosRegistration getRegistration() {if (this.registration.getPort() 0 this.getPort().get() 0) {this.registration.setPort(this.getPort().get());}Assert.isTrue(this.registration.getPort() 0, service.port has not been set);return this.registration;}protected NacosRegistration getManagementRegistration() {return null;}protected void register() {if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {log.debug(Registration disabled.);} else {if (this.registration.getPort() 0) {this.registration.setPort(this.getPort().get());}super.register();}}protected void registerManagement() {if (this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {super.registerManagement();}}protected int getConfiguredPort() {return this.getPort().get();}protected void setConfiguredPort(int port) {this.getPort().set(port);}protected Object getConfiguration() {return this.registration.getNacosDiscoveryProperties();}protected boolean isEnabled() {return this.registration.getNacosDiscoveryProperties().isRegisterEnabled();}protected String getAppName() {String appName this.registration.getNacosDiscoveryProperties().getService();return StringUtils.isEmpty(appName) ? super.getAppName() : appName;}
} 3.4.2 没有发现如何启动继续查看父类 3.4.2.1 源码
package org.springframework.cloud.client.serviceregistry;import org.springframework.cloud.client.discovery.AbstractDiscoveryLifecycle;public abstract class AbstractAutoServiceRegistrationR extends Registration extends AbstractDiscoveryLifecycle implements AutoServiceRegistration {private final ServiceRegistryR serviceRegistry;private AutoServiceRegistrationProperties properties;/** deprecated */Deprecatedprotected AbstractAutoServiceRegistration(ServiceRegistryR serviceRegistry) {this.serviceRegistry serviceRegistry;}protected AbstractAutoServiceRegistration(ServiceRegistryR serviceRegistry, AutoServiceRegistrationProperties properties) {this.serviceRegistry serviceRegistry;this.properties properties;}protected ServiceRegistryR getServiceRegistry() {return this.serviceRegistry;}protected abstract R getRegistration();protected abstract R getManagementRegistration();protected void register() {this.serviceRegistry.register(this.getRegistration());}protected void registerManagement() {R registration this.getManagementRegistration();if (registration ! null) {this.serviceRegistry.register(registration);}}protected void deregister() {this.serviceRegistry.deregister(this.getRegistration());}protected void deregisterManagement() {R registration this.getManagementRegistration();if (registration ! null) {this.serviceRegistry.deregister(registration);}}public void stop() {if (this.getRunning().compareAndSet(true, false) this.isEnabled()) {this.deregister();if (this.shouldRegisterManagement()) {this.deregisterManagement();}this.serviceRegistry.close();}}protected boolean shouldRegisterManagement() {return this.properties ! null !this.properties.isRegisterManagement() ? false : super.shouldRegisterManagement();}
} 3.4.2.2 注 注意此时包名换了。现在是spring框架源码并且继承了AbstractDiscoveryLifecycle 3.5 查看 AbstractDiscoveryLifecycle 3.5.1 AbstractDiscoveryLifecycle源码
Deprecated
public abstract class AbstractDiscoveryLifecycle implements DiscoveryLifecycle, ApplicationContextAware, ApplicationListenerEmbeddedServletContainerInitializedEvent {private static final Log logger LogFactory.getLog(AbstractDiscoveryLifecycle.class);private boolean autoStartup true;private AtomicBoolean running new AtomicBoolean(false);private int order 0;private ApplicationContext context;private Environment environment;private AtomicInteger port new AtomicInteger(0);public AbstractDiscoveryLifecycle() {}protected ApplicationContext getContext() {return this.context;}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context applicationContext;this.environment this.context.getEnvironment();}/** deprecated */Deprecatedprotected Environment getEnvironment() {return this.environment;}/** deprecated */Deprecatedprotected AtomicInteger getPort() {return this.port;}public boolean isAutoStartup() {return this.autoStartup;}public void stop(Runnable callback) {try {this.stop();} catch (Exception var3) {logger.error(A problem occurred attempting to stop discovery lifecycle, var3);}callback.run();}public void start() {if (!this.isEnabled()) {if (logger.isDebugEnabled()) {logger.debug(Discovery Lifecycle disabled. Not starting);}} else {if (this.port.get() ! 0 this.getConfiguredPort() 0) {this.setConfiguredPort(this.port.get());}if (!this.running.get() this.getConfiguredPort() 0) {this.register();if (this.shouldRegisterManagement()) {this.registerManagement();}this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));this.running.compareAndSet(false, true);}}}/** deprecated */Deprecatedprotected abstract int getConfiguredPort();/** deprecated */Deprecatedprotected abstract void setConfiguredPort(int var1);protected boolean shouldRegisterManagement() {return this.getManagementPort() ! null ManagementServerPortUtils.isDifferent(this.context);}/** deprecated */Deprecatedprotected abstract Object getConfiguration();protected abstract void register();protected void registerManagement() {}protected abstract void deregister();protected void deregisterManagement() {}protected abstract boolean isEnabled();/** deprecated */Deprecatedprotected String getManagementServiceId() {return this.context.getId() :management;}/** deprecated */Deprecatedprotected String getManagementServiceName() {return this.getAppName() :management;}/** deprecated */Deprecatedprotected Integer getManagementPort() {return ManagementServerPortUtils.getPort(this.context);}/** deprecated */Deprecatedprotected String getAppName() {return this.environment.getProperty(spring.application.name, application);}public void stop() {if (this.running.compareAndSet(true, false) this.isEnabled()) {this.deregister();if (this.shouldRegisterManagement()) {this.deregisterManagement();}}}PreDestroypublic void destroy() {this.stop();}public boolean isRunning() {return this.running.get();}protected AtomicBoolean getRunning() {return this.running;}public int getOrder() {return this.order;}public int getPhase() {return 0;}// ***************************************************************// 重点// *************************************************************** /** deprecated */Deprecatedpublic void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {if (!management.equals(event.getApplicationContext().getNamespace())) {this.port.compareAndSet(0, event.getEmbeddedServletContainer().getPort());this.start();}}
} 3.5.2 注 AbstractDiscoveryLifecycle抽象类继承了ApplicationListener该类需要实现方法onApplicationEvent且此方法就在AbstractDiscoveryLifecycle。 该方法调用了this.start() 3.6 查看this.start() 3.6.1 源码:
public void start() {if (!this.isEnabled()) {if (logger.isDebugEnabled()) {logger.debug(Discovery Lifecycle disabled. Not starting);}} else {if (this.port.get() ! 0 this.getConfiguredPort() 0) {this.setConfiguredPort(this.port.get());}if (!this.running.get() this.getConfiguredPort() 0) {this.register();if (this.shouldRegisterManagement()) {this.registerManagement();}// 这个地方发布了一个服务注册事件订阅不知道在哪 this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));this.running.compareAndSet(false, true);}}} 3.6.2 注 start()方法内调用了this.register() 并且此方法仍旧在AbstractDiscoveryLifecycle类中且在spring 框架内说明spring 留了一个口子spi来帮助实现服务注册功能自己想做服务注册只要继承AbstractDiscoveryLifecycle 重写register方法即可
3.7 点击this.register() : 发现仍在AbstractDiscoveryLifecycle且是个抽象类并没有具体实现 pr4otected abstract void register(); 3.8 idea 点击实现类 找到NacosAutoServiceREgistration 实现类 3.9 实现方法 protected void register() {if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {log.debug(Registration disabled.);} else {if (this.registration.getPort() 0) {this.registration.setPort(this.getPort().get());}super.register();}}4.0 继续跟踪super.register()
public abstract class AbstractAutoServiceRegistrationR extends Registration extends AbstractDiscoveryLifecycle implements AutoServiceRegistration {// *****省略protected void register() {this.serviceRegistry.register(this.getRegistration());}} 4.1 this.serviceRegistry.register(this.getRegistration());
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.cloud.client.serviceregistry;public interface ServiceRegistryR extends Registration {void register(R var1);void deregister(R var1);void close();void setStatus(R var1, String var2);T T getStatus(R var1);
}4.2 点击register 实现则 发现为NacosServiceRegistry 实现类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.alibaba.cloud.nacos.registry;import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.util.StringUtils;public class NacosServiceRegistry implements ServiceRegistryRegistration {private static final Logger log LoggerFactory.getLogger(NacosServiceRegistry.class);private final NacosDiscoveryProperties nacosDiscoveryProperties;private final NamingService namingService;public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {this.nacosDiscoveryProperties nacosDiscoveryProperties;this.namingService nacosDiscoveryProperties.namingServiceInstance();}// NacosServiceRegistry 实现spring 框架类ServiceRegistry的register方法 public void register(Registration registration) {if (StringUtils.isEmpty(registration.getServiceId())) {log.warn(No service to register for nacos client...);} else {String serviceId registration.getServiceId();Instance instance this.getNacosInstanceFromRegistration(registration);try {this.namingService.registerInstance(serviceId, instance);log.info(nacos registry, {} {}:{} register finished, new Object[]{serviceId, instance.getIp(), instance.getPort()});} catch (Exception var5) {log.error(nacos registry, {} register failed...{},, new Object[]{serviceId, registration.toString(), var5});}}}public void deregister(Registration registration) {log.info(De-registering from Nacos Server now...);if (StringUtils.isEmpty(registration.getServiceId())) {log.warn(No dom to de-register for nacos client...);} else {NamingService namingService this.nacosDiscoveryProperties.namingServiceInstance();String serviceId registration.getServiceId();try {namingService.deregisterInstance(serviceId, registration.getHost(), registration.getPort(), this.nacosDiscoveryProperties.getClusterName());} catch (Exception var5) {log.error(ERR_NACOS_DEREGISTER, de-register failed...{},, registration.toString(), var5);}log.info(De-registration finished.);}}public void close() {}public void setStatus(Registration registration, String status) {if (!status.equalsIgnoreCase(UP) !status.equalsIgnoreCase(DOWN)) {log.warn(cant support status {},please choose UP or DOWN, status);} else {String serviceId registration.getServiceId();Instance instance this.getNacosInstanceFromRegistration(registration);if (status.equalsIgnoreCase(DOWN)) {instance.setEnabled(false);} else {instance.setEnabled(true);}try {this.nacosDiscoveryProperties.namingMaintainServiceInstance().updateInstance(serviceId, instance);} catch (Exception var6) {throw new RuntimeException(update nacos instance status fail, var6);}}}public Object getStatus(Registration registration) {String serviceName registration.getServiceId();try {ListInstance instances this.nacosDiscoveryProperties.namingServiceInstance().getAllInstances(serviceName);Iterator var4 instances.iterator();while(var4.hasNext()) {Instance instance (Instance)var4.next();if (instance.getIp().equalsIgnoreCase(this.nacosDiscoveryProperties.getIp()) instance.getPort() this.nacosDiscoveryProperties.getPort()) {return instance.isEnabled() ? UP : DOWN;}}} catch (Exception var6) {log.error(get all instance of {} error,, serviceName, var6);}return null;}private Instance getNacosInstanceFromRegistration(Registration registration) {Instance instance new Instance();instance.setIp(registration.getHost());instance.setPort(registration.getPort());instance.setWeight((double)this.nacosDiscoveryProperties.getWeight());instance.setClusterName(this.nacosDiscoveryProperties.getClusterName());instance.setMetadata(registration.getMetadata());return instance;}
}4.2.1 调用链路实现闭环 1. spring boot 自动装配META-INF/spring.factories 2. 第一个就是NacosDiscoveryAutoConfiguration 且该类创建三个Bean对象NacosServiceRegistry, NacosRegistration,NacosAutoServiceRegistration3. 核心NacosAutoServiceRegistration类继承AbstractAutoServiceRegistration 4. AbstractAutoServiceRegistration为spring 框架内容且继承AbstractDiscoveryLifecycle
5. AbstractDiscoveryLifecycle实现了ApplicationListener的onApplicationEvent方法
6. onApplicationEvent内调用了this.start();
7. this.start 调用了this.register
8. NacosAutoServiceRegistration实现了this.register 并调用方法super.register()
9. 调用父类register(),此时为spring 框架方法 且调用了this.serviceRegistry.register(this.getRegistration());
10.register为接口spring未提供实现类由nacos的NacosServiceRegistry
类实现register方法
11. NacosServiceRegistry类register方法内调用了this.namingService.registerInstance(serviceId, instance); 12. 最终到达ncos源码中client 模块的注册服务方法 13. 为NacosNamingServiceregis.registerInstance(serviceId, instance);
5. 总结:
5.1 本文主要讲了spring cloud alibaba 的starter模块下的 discovery模块讲了客户端依赖了discovery 之后它是是如何步一步到达nacos源码过程 5.2 读了源码后发现spring 已为服务注册留下了spi 配合spring boot自动装配自己也可以实现一个client, server。继承AbstractAutoServiceRegistration 以及实现register()等
5.3 读万卷书不如行万里路建议自己动手实际去看看收获才是最多的 注本人能力有限还请多多包涵亦欢迎大佬指正错误