一.Nacos源码搭建
源码地址:git clone https://gitee.com/mirrors/Nacos.git
启动问题1.找不到类在ideal控制台使用:mvn compile启动问题2.服务找不到(nacos默认使用集群形式)-Dnacos.standalone=true


二、nacos2.0.3依赖包
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.6.RELEASE</version><exclusions><exclusion><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.6.RELEASE</version><exclusions><exclusion><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
二. Nacos启动注入类
NacosDiscoveryClientConfiguration
@Configuration(proxyBeanMethods = false)@ConditionalOnDiscoveryEnabled@ConditionalOnBlockingDiscoveryEnabled@ConditionalOnNacosDiscoveryEnabled@AutoConfigureBefore({SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class})@AutoConfigureAfter({NacosDiscoveryAutoConfiguration.class})public class NacosDiscoveryClientConfiguration {public NacosDiscoveryClientConfiguration() {}@Beanpublic DiscoveryClient nacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {return new NacosDiscoveryClient(nacosServiceDiscovery);}@Bean@ConditionalOnMissingBean@ConditionalOnProperty(value = {"spring.cloud.nacos.discovery.watch.enabled"},matchIfMissing = true)public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties) {return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties);}}
NacosDiscoveryClient
public class NacosDiscoveryClient implements DiscoveryClient {private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class);public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";private NacosServiceDiscovery serviceDiscovery;public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {this.serviceDiscovery = nacosServiceDiscovery;}}
NacosWatch
观察者创建定时任务线程池(Nacos-Watch-Task-Scheduler),默认有一个线程,使用AbortPolicy拒绝策略
public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle {private static final Logger log = LoggerFactory.getLogger(NacosWatch.class);private Map<String, EventListener> listenerMap = new ConcurrentHashMap(16);private final AtomicBoolean running = new AtomicBoolean(false);private final AtomicLong nacosWatchIndex = new AtomicLong(0L);private ApplicationEventPublisher publisher;private ScheduledFuture<?> watchFuture;private NacosServiceManager nacosServiceManager;private final NacosDiscoveryProperties properties;private final ThreadPoolTaskScheduler taskScheduler;public NacosWatch(NacosServiceManager nacosServiceManager, NacosDiscoveryProperties properties) {this.nacosServiceManager = nacosServiceManager;this.properties = properties;this.taskScheduler = getTaskScheduler();}private static ThreadPoolTaskScheduler getTaskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setBeanName("Nacos-Watch-Task-Scheduler");taskScheduler.initialize();return taskScheduler;}public void initialize() {if (this.logger.isInfoEnabled()) {this.logger.info("Initializing ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));}if (!this.threadNamePrefixSet && this.beanName != null) {this.setThreadNamePrefix(this.beanName + "-");}#使用AbortPolicy策略:丢弃任务并抛出RejectedExecutionException异常this.executor = this.initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);}}
NacosDiscoveryAutoConfiguration
@Configuration@EnableConfigurationProperties@ConditionalOnNacosDiscoveryEnabled@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);}@Bean@ConditionalOnBean({AutoServiceRegistrationProperties.class})public NacosRegistration nacosRegistration(NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) {return new NacosRegistration(nacosDiscoveryProperties, context);}@Bean@ConditionalOnBean({AutoServiceRegistrationProperties.class})public NacosAutoServiceRegistration nacosAutoServiceRegistration(NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);}}
NacosRegistration
public class NacosRegistration implements Registration, ServiceInstance {public static final String MANAGEMENT_PORT = "management.port";public static final String MANAGEMENT_CONTEXT_PATH = "management.context-path";public static final String MANAGEMENT_ADDRESS = "management.address";public static final String MANAGEMENT_ENDPOINT_BASE_PATH = "management.endpoints.web.base-path";private NacosDiscoveryProperties nacosDiscoveryProperties;private ApplicationContext context;public NacosRegistration(NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) {this.nacosDiscoveryProperties = nacosDiscoveryProperties;this.context = context;}@PostConstructpublic void init() {Map<String, String> metadata = this.nacosDiscoveryProperties.getMetadata();Environment env = this.context.getEnvironment();String endpointBasePath = env.getProperty("management.endpoints.web.base-path");if (!StringUtils.isEmpty(endpointBasePath)) {metadata.put("management.endpoints.web.base-path", endpointBasePath);}Integer managementPort = ManagementServerPortUtils.getPort(this.context);if (null != managementPort) {metadata.put("management.port", managementPort.toString());String contextPath = env.getProperty("management.server.servlet.context-path");String address = env.getProperty("management.server.address");if (!StringUtils.isEmpty(contextPath)) {metadata.put("management.context-path", contextPath);}if (!StringUtils.isEmpty(address)) {metadata.put("management.address", address);}}if (null != this.nacosDiscoveryProperties.getHeartBeatInterval()) {metadata.put("preserved.heart.beat.interval", this.nacosDiscoveryProperties.getHeartBeatInterval().toString());}if (null != this.nacosDiscoveryProperties.getHeartBeatTimeout()) {metadata.put("preserved.heart.beat.timeout", this.nacosDiscoveryProperties.getHeartBeatTimeout().toString());}if (null != this.nacosDiscoveryProperties.getIpDeleteTimeout()) {metadata.put("preserved.ip.delete.timeout", this.nacosDiscoveryProperties.getIpDeleteTimeout().toString());}}}
NacosServiceRegistry
public class NacosServiceRegistry implements ServiceRegistry<Registration> {private static final Logger log = LoggerFactory.getLogger(NacosServiceRegistry.class);private final NacosDiscoveryProperties nacosDiscoveryProperties;private final NamingService namingService;public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {this.nacosDiscoveryProperties = nacosDiscoveryProperties;#这里会将namingService 注册进容器this.namingService = nacosDiscoveryProperties.namingServiceInstance();}public NamingService namingServiceInstance() {if (null != this.namingService) {return this.namingService;} else {try {#这里通过构造器反射获取实例this.namingService = NacosFactory.createNamingService(this.getNacosProperties());} catch (Exception var2) {log.error("create naming service error!properties={},e=,", this, var2);return null;}return this.namingService;}}}
NacosNamingService
public class NacosNamingService implements NamingService {private static final String DEFAULT_PORT = "8080";private static final long DEFAULT_HEART_BEAT_INTERVAL;private String namespace;private String endpoint;private String serverList;private String cacheDir;private String logName;private HostReactor hostReactor;private BeatReactor beatReactor;private EventDispatcher eventDispatcher;private NamingProxy serverProxy;public NacosNamingService(String serverList) {Properties properties = new Properties();properties.setProperty("serverAddr", serverList);this.init(properties);}public NacosNamingService(Properties properties) {this.init(properties);}private void init(Properties properties) {this.namespace = InitUtils.initNamespaceForNaming(properties);this.initServerAddr(properties);InitUtils.initWebRootContext();this.initCacheDir();this.initLogName(properties);this.eventDispatcher = new EventDispatcher();this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList);this.serverProxy.setProperties(properties);this.beatReactor = new BeatReactor(this.serverProxy, this.initClientBeatThreadCount(properties));this.hostReactor = new HostReactor(this.eventDispatcher, this.serverProxy, this.cacheDir, this.isLoadCacheAtStart(properties), this.initPollingThreadCount(properties));}private int initClientBeatThreadCount(Properties properties) {return properties == null ? UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT : NumberUtils.toInt(properties.getProperty("namingClientBeatThreadCount"), UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);}}
NacosDiscoveryProperties
@ConfigurationProperties("spring.cloud.nacos.discovery")public class NacosDiscoveryProperties {private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryProperties.class);private String serverAddr;private String endpoint; # 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址private String namespace;private long watchDelay = 30000L;private String logName;# 日志文件名@Value("${spring.cloud.nacos.discovery.service:${spring.application.name:}}")private String service;private float weight = 1.0F;#取值范围 1 到 100,数值越大,权重越大private String clusterName = "DEFAULT";private String namingLoadCacheAtStart = "false";private Map<String, String> metadata = new HashMap();#使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息private boolean registerEnabled = true;private String ip;# 优先级最高private String networkInterface = "";#当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址private int port = -1;# 默认情况下不用配置,会自动探测private boolean secure = false;private String accessKey;# 当要上阿里云时,阿里云上面的一个云账号名private String secretKey;# 当要上阿里云时,阿里云上面的一个云账号密码private Integer heartBeatInterval;private Integer heartBeatTimeout;private Integer ipDeleteTimeout;@Autowiredprivate InetUtils inetUtils;@Autowiredprivate Environment environment;private NamingService namingService;private NamingMaintainService namingMaintainService;public NacosDiscoveryProperties() {}@PostConstructpublic void init() throws SocketException {this.metadata.put("preserved.register.source", "SPRING_CLOUD");if (this.secure) {this.metadata.put("secure", "true");}this.serverAddr = Objects.toString(this.serverAddr, "");if (this.serverAddr.lastIndexOf("/") != -1) {this.serverAddr = this.serverAddr.substring(0, this.serverAddr.length() - 1);}this.endpoint = Objects.toString(this.endpoint, "");this.namespace = Objects.toString(this.namespace, "");this.logName = Objects.toString(this.logName, "");if (StringUtils.isEmpty(this.ip)) {if (StringUtils.isEmpty(this.networkInterface)) {this.ip = this.inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();} else {NetworkInterface netInterface = NetworkInterface.getByName(this.networkInterface);if (null == netInterface) {throw new IllegalArgumentException("no such interface " + this.networkInterface);}Enumeration inetAddress = netInterface.getInetAddresses();while(inetAddress.hasMoreElements()) {InetAddress currentAddress = (InetAddress)inetAddress.nextElement();if (currentAddress instanceof Inet4Address && !currentAddress.isLoopbackAddress()) {this.ip = currentAddress.getHostAddress();break;}}if (StringUtils.isEmpty(this.ip)) {throw new RuntimeException("cannot find available ip from network interface " + this.networkInterface);}}}this.overrideFromEnv(this.environment);}}
