Nacos Client2.2.9源码启动问题
1、开启服务端
源码启动,推荐使用稳定版本作为 服务端。
我是用了最新的2.2.1的nacos版本处理了一些问题,现在启动成功
nacos首页
http://192.168.3.111:8848/nacos/index.html
2、配置客户端client
直接一个springboot项目。
写一个controller
2.1 把当前springboot升级为springCloud项目
maven的pom配置修改
springboot 版本 2.3.12.RELEASE
Spring Cloud Version Hoxton.SR12
Spring Cloud Alibaba Version 2.2.9.RELEASE
如我的配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shine</groupId>
<artifactId>nacosClientDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>nacosClientDemo</name>
<description>nacosClientDemo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<!--springboot 要使用 cloudlibaba的功能,先引入 cloud的依赖,然后再引入 cloudalibaba的依赖,因为 cloudalibaba的依赖 是 cloud 的子工程 -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.1 配置yaml
server:
port: 10001
spring:
application:
name: nacosClientDemo
//注册服务地址
cloud:
nacos:
server-addr: 192.168.3.111:8848
注册成功
再通过一个client启动一个微服务。
3、看看client注册做了什么
3.1、client 注册时,如何打断点
3.1.1、找这个服务发现的包。
3.1.2 下面的spring.factories
3.1.3 下面的NacosDiscoveryAutoConfiguration
同命名下面的 自动配置
com.alibaba.cloud.nacos.discovery
NacosDiscoveryAutoConfiguration
3.1.4 点进去发现配置文件
public class NacosDiscoveryAutoConfiguration {
public NacosDiscoveryAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean
public NacosDiscoveryProperties nacosProperties() {
return new NacosDiscoveryProperties();
}
@Bean
@ConditionalOnMissingBean
public NacosServiceDiscovery nacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) {
return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager);
}
}
3.1.5关键重点是 nacosServiceDiscovery
我的是版本有点问题。
应该是NacosServiceRegistryAutoConfiguration,
3.1.6 NacosServiceRegistryAutoConfiguration,
NacosAutoServiceRegistration
最后没有到http,太搞笑了。
走的是grpc的代理方法。
那应用是跟踪哪个类?
这里,我提供两种方法。
1、代码分析法,如果有多个实现类,肯定在前面的某个步骤会去创建该类,因为这个类不会无缘无故的就产生的。计算机的程序代码是很规范的,你要他怎么做,他才怎么做,不会无故产生,俗话说事出反常必有妖。
2、断点调试法,这个方法简单粗暴,只要你debug一下,跟着debug进去,到哪个类处理,那就是哪个类处理。
我们还是倒回来看下,通过代码分析具体一下。还记得上面说的创建NamingService吗,这里我们进去看下这个NamingService的具体的实现方法NacosNamingService的构造方法。
有一个初始化方法。获取代理模式
private void init(Properties properties) throws NacosException {
ValidatorUtils.checkInitParam(properties);
this.namespace = InitUtils.initNamespaceForNaming(properties);
InitUtils.initSerialization();
InitUtils.initWebRootContext(properties);
initLogName(properties);
this.changeNotifier = new InstancesChangeNotifier();
NotifyCenter.registerToPublisher(InstancesChangeEvent.class, 16384);
NotifyCenter.registerSubscriber(changeNotifier);
this.serviceInfoHolder = new ServiceInfoHolder(namespace, properties);
this.clientProxy = new NamingClientProxyDelegate(this.namespace, serviceInfoHolder, properties, changeNotifier);
}
这个代理执行器。
代理模式的作用就是这个意思。
要执行的具体方法都在这个代理执行器里面。
private NamingClientProxy getExecuteClientProxy(Instance instance) {
return instance.isEphemeral() ? grpcClientProxy : httpClientProxy;
}
可以看到如果是临时实例,就是用 grpc
永久实例,就用httpClientProxy。
3.1.6 重点是那个代理类
3.1.7 重点是 instance.isEphemeral()是否是临时实例
决定是走 http还是走grpc