1. Nacos简介

2018年6⽉, Eureka 2.0宣布闭源(但是1.X版本仍然为活跃项⽬), 同年7⽉份, 阿⾥Nacos宣布开源. 并快速成为国内最受关注开源产品. 作为Eureka的替代, Nacos已经成为了国内开发者的⾸选, ⽬前NacosStar 已经突破28K(Eureka 12K)

Nacos (Dynamic Naming and Configuration Service)

在最初开源时, Nacos选择进⾏内部三个产品合并统⼀开源(Configserver ⾮持久注册中⼼,VIPServer持久化注册中⼼,Diamond 配置中⼼). 定位为:⼀个更易于构建云原⽣应⽤的动态服务发现, 配置管理和服务管理平台. 所以Nacos是⼀个注册中⼼组件, 但它⼜不仅仅是注册中⼼组件.

截⾄⽬前, Nacos⼏乎⽀持了所有的主流语⾔, ⽐如 Java, Go, C++, Nodejs, Python, Scala等

官⽹:https://nacos.io/

仓库:https://github.com/alibaba/nacos

2. Nacos安装

2.1 下载安装包

⽬前官⽅推荐的稳定版本为2.2.3, 咱们课程中也是⽤2.2.3

下载地址 https://github.com/alibaba/nacos/releases/tag/2.2.3

其他版本下载链接: 下载链接: https://github.com/alibaba/nacos/releases

2.2 Windows

2.2.1 解压

把压缩包解压到任意⾮中⽂的⽬录下

⽬录介绍:

bin: Nacos启停脚本

• startup.cmd :windows平台的启动脚本

• startup.sh :Linux平台的启动脚本

• shutdown.cmd : windows平台的停⽌脚本

• shutdown.sh : Linux平台的停⽌脚本

conf: Nacos配置⽂件

target: 存放 Nacos 应⽤的 jar 包

2.2.2 修改单机模式

Nacos 默认启动⽅式为集群, 启动前需要修改配置为单机模式.

1. 使⽤记事本打开 startup.cmd

2. Line 26左右, 修改启动模式

set MODE="cluster" 改为 set MODE="standalone"

如图所示:

2.2.3 启动Nacos

启动⾮常简单, 进⼊bin⽬录下, 双击 startup.cmd 即可

访问Nacos主⻚, 出现以下界⾯, 表⽰Nacos启动成功

http://127.0.0.1:8848/nacos

2.2.4 常见问题

Nacos启动后, ⽬录下会多⼀个logs的⽂件夹

报错⽇志在: logs/nacos.log

集群模式启动

报错⽇志

Nacos默认是集群(cluster)启动,将其设置为单机(standalone), 设置⽅式参考 上⾯章节

端⼝号冲突

Nacos 默认端⼝号是8848, 如果该端⼝号被其他应⽤占⽤, 启动会报错:

解决⽅式有以下两种, 任选其⼀:

1. 关闭该进程

a. 打开cmd

Win + R, 弹出命令提⽰符, 输⼊cmd

b. 查找进程

输⼊命令

netstat -ano|findstr "8848"

c.杀掉进程

taskkill /pid 4968 -f

2. 修改Nacos端⼝号

修改⽂件: ${Nacos⽬录}/conf/application.properties

23⾏左右

修改8848为期望的端⼝号即可.

2.3 Linux

2.3.1 准备安装包

上传提前下载好的安装包到服务器上某个⽬录, ⽐如 /usr/local/src

解压安装包

unzip nacos-server-2.2.3.zip

如果第⼀次使⽤, 未安装unzip命令, 需要安装⼀下

apt-get install unzip

解压后目录如下:

2.3.1 单机模式启动

进入nacos/bin目录,输入命令:

bash startup.sh -m standalone

上述命令为Ubuntu系统的命令

nacos安装前需要先安装JDK

CenterOS使⽤: sh startup.sh -m standalone

启动成功后, 访问Nacos链接: http://IP:port/nacos

10020为修改后的端⼝号, 需要在服务器上开放对应的端⼝号

另外, 再开放 Nacos端⼝号+1000 和 Nacos端⼝号+1001 的端⼝

⽐如端⼝号为10020, 则需要开放端⼝号为: 10020, 11020, 11021 

端⼝号为8848, 则需要开放端⼝号为: 9848, 9849

3. Nacos快速上手

Nacos是Spring Cloud Alibaba的组件, Spring Cloud Alibaba遵循Spring Cloud中定义的服务注册, 服务发现规范. 因此使⽤Nacos和使⽤Eureka对于微服务来说,并没有太⼤区别.

主要差异在于:

• Eureka需要⾃⼰搭建⼀个服务, Nacos不⽤⾃⼰搭建服务, 组件已经准备好了, 只需启动即可.

• 对应依赖和配置不同

操作参考: https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

3.1 服务注册/服务发现

引⼊Spring Cloud Alibaba依赖

在⽗⼯程的pom⽂件中的 <dependencyManagement> 中引⼊Spring Cloud Alibaba的依赖:

<properties>
    <spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>

 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-alibaba-dependencies</artifactId>
     <version>${spring-cloud-alibaba.version}</version>
     <type>pom</type>
     <scope>import</scope>
 </dependency>

注意: Spring Boot 和Spring Cloud的版本是有⼀定对应关系的. Spring Cloud Alibaba也遵循Spring Cloud 的标准, 在引⼊依赖时, ⼀定要确认各个版本的对应关系.

Spring Cloud Alibaba 和Spring Cloud版本对应关系, 参考官⽅⽂档:

https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/overview/version-explain/

版本在⼀定范围内可以⾃由选择

引⼊Nacos 依赖

在order-service和product-service中引⼊nacos依赖

 <dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

引⼊Load Balance依赖

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

3.2 配置Nacos地址

这里我们直接使用服务器Nacos地址

spring:
 application:
 name: product-service
 cloud:
 nacos:
 discovery:
 server-addr: xxx.xx.xx.xx:10020

也可以改成本地Nacos的IP: 127.0.0.1:8848

3.3 远程调用

1. 修改IP为项目名

public OrderInfo selectOrderById(Integer orderId) {
 OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
 String url = "http://product-service/product/"+ orderInfo.getProductId();
 ProductInfo productInfo = restTemplate.getForObject(url, 
ProductInfo.class);
 orderInfo.setProductInfo(productInfo);
 return orderInfo;
 }

2. 为restTemplate添加负载均衡注解@LoadBalanced

@Configuration
 public class BeanConfig {
 @Bean
 @LoadBalanced
 public RestTemplate restTemplate(){
 return new RestTemplate();
 }

3.4 启动服务

启动两个服务, 观察Nacos的管理界⾯, 发现order-service 和product-service 都注册在Nacos上了

测试接⼝: http://127.0.0.1:8080/order/1

3.5 启动多个服务,测试负载均衡

启动三个product-service服务

观察Nacos控制台

多次访问接口,观察日志

http://127.0.0.1:8080/order/1

3.6 常见问题

java.net.UnknownHostException

检查是否添加 LoadBalance 依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

服务注册失败

可能没有报错⽇志, 或者报错⽇志如下(与版本有关)

检查Spring Cloud Alibaba版本是否正确

参考: 版本发布说明 | Spring Cloud Alibaba

4. Nacos负载均衡

⽣产环境相对是⽐较恶劣的, 我们需要对服务的流量进⾏更加精细的控制. Nacos⽀持多种负载均衡策略, 包括权重, 同机房, 同地域, 同环境等.

4.1 服务下线

当某⼀个节点上接⼝的性能较差时, 我们可以第⼀时间对该节点进⾏下线.

操作步骤: 服务详情 -> 下线

点击下线后, 再次请求接⼝, 会发现该服务没有请求进来了

再次单击上线, 该节点会继续收到请求.

4.2 权重配置

除了下线之外,我们也可以配置这个节点的流量权重

4.2.1 配置权重

操作步骤: 找到对应节点 ->编辑 -> 在弹出的窗⼝修改权重值

每个节点默认权重为1, 修改为0.1.

4.2.2 开启Nacos负载均衡策略

由于Spring Cloud LoadBalance组件⾃⾝有负载均衡配置⽅式, 所以不⽀持Nacos的权重属性配置.我们需要开启Nacos的负载均衡策略, 让权重配置⽣效

参考: 如何解决MSE Nacos上修改服务实例的权重不⽣效问题_微服务引擎(MSE)-阿⾥云帮助中⼼

#开启nacos的负载均衡策略
 spring.cloud.loadbalancer.nacos.enabled=true

 spring:
 cloud:
 loadbalancer:
 nacos:
 enabled: true

4.2.3 测试权重配置

启动服务, 访问多次接⼝, 观察结果, 会发现9091端⼝号的实例接收的请求明显⽐另外两个实例少

整体流量⽣效, 局部流量不是严格按照设置的⽐例进⾏分配的

4.2.4常见问题

修改权重时,可能会报错:

原因: Nacos 采⽤ raft 算法来计算 Leader, 并且会记录前⼀次启动的集群地址, 当服务器 IP 改变时会导致 raft 记录的集群地址失效, 导致选 Leader 出现问题. (⽹络环境发⽣变化时, IP地址也会发⽣变化)

解决办法: 删除 Nacos 根⽬录下 data ⽂件夹下的 protocol ⽂件夹即可

4.3 同集群优先访问

Nacos把同⼀个机房内的实例, 划分为⼀个集群. 所以同集群优先访问, 在⼀定程度上也可以理解为同机房优先访问.

微服务架构中, ⼀个服务通常有多个实例共同提供服务, 这些实例可以部署在不同的机器上, 这些机器可以分布在不同的机房, ⽐如product-service:

实例1: 分布在上海机房

实例2: 分布在上海机房

实例3: 分布在北京机房

实例4: 分布在北京机房

微服务访问时, 应尽量访问同机房的实例. 当本机房内实例不可⽤时, 才访问其他机房的实例.

⽐如order-service 在上海机房, product-service 在北京和上海机房都有实例, 那我们希望可以优先访问上海机房, 如果上海机房没有实例, 或者实例不可⽤, 再访问北京机房的实例. 通常情况下, 因为同⼀个机房的机器属于⼀个局域⽹, 局域⽹访问速度更快⼀点.

4.3.1 给实例配置集群名称

1. 为product-service配置集群名称

spring:
 cloud:
 nacos:
 discovery:
 server-addr: xxx.xx.xx.xx:10020
 cluster-name: SH #集群名称: 上海集群

重启服务,观察Nacos控制台,SH集群多了一个实例

复制product-service启动配置, 添加VM Option

设置9091端⼝号的实例, 机房为BJ

-Dserver.port=9091 -Dspring.cloud.nacos.discovery.cluster-name=BJ

设置9092端⼝号的实例, 机房为BJ

 -Dserver.port=9091 -Dspring.cloud.nacos.discovery.cluster-name=BJ

观察Nacos, BJ集群下多了⼀个实例

2. 为order-service配置集群名称:SH

spring:
 cloud:
 nacos:
 discovery:
 server-addr: xxx.xx.xx.xx:10020
 cluster-name: SH #集群名称: 上海集群

4.3.2 开启Nacos负载均衡策略

同权重配置

#开启nacos的负载均衡策略
 spring.cloud.loadbalancer.nacos.enabled=true

 spring:
     cloud:
         loadbalancer:
             nacos:
                 enabled: true

4.3.3 测试

启动服务 

1. 对接⼝访问多次, 观察⽇志, 会发现只有9090端⼝的实例收到了请求(同集群)

2. 把9090端⼝的实例进⾏下线(SH集群), 再次访问接⼝, 观察⽇志, 发现9091端⼝和9092端⼝的实例收到了请求

5. Nacos健康检查

5.1 两种健康检查机制

Nacos作为注册中⼼, 需要感知服务的健康状态, 才能为服务调⽤⽅提供良好的服务.

Nacos 中提供了两种健康检查机制:

客⼾端主动上报机制:

  • 客⼾端通过⼼跳上报⽅式告知服务端(nacos注册中⼼)健康状态, 默认⼼跳间隔5秒;
  • nacos会在超过15秒未收到⼼跳后将实例设置为不健康状态, 超过30秒将实例删除

服务器端反向探测机制:

  • nacos主动探知客⼾端健康状态, 默认间隔为20秒.
  • 健康检查失败后实例会被标记为不健康, 不会被⽴即删除.

⽐如领导管理员⼯的⼯作

1. 员⼯主动汇报: 员⼯每天主动汇报⾃⼰⼯作进度

2. 领导主动问询: 领导每周向员⼯了解⼯作进度

Nacos 中的健康检查机制不能主动设置,健康检查机制是和 Nacos 的服务实例类型强相关的.

5.2 Nacos服务实例类型

Nacos的服务实例(注册的节点)分为临时实例和⾮临时实例.

  • 临时实例: 如果实例宕机超过⼀定时间, 会从服务列表剔除, 默认类型.
  • ⾮临时实例: 如果实例宕机, 不会从服务列表剔除, 也可以叫永久实例

Nacos对临时实例, 采取的是 客⼾端主动上报机制, 对⾮临时实例, 采取服务器端反向探测机制.

配置⼀个服务实例为永久实例

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为⾮临时实例

重启服务,观察Nacos控制台

停止服务,再观察控制台

节点依然不会消失.

5.3 常见问题

5.3.1 Nacos服务实例类型不允许改变

设置服务实例类型, 重新启动Nacos可能会报错

报错信息参考:

Caused by: com.alibaba.nacos.api.exception.NacosException: failed to req 
API:/nacos/v1/ns/instance after all servers([110.41.51.65:10020]) tried: 
caused: errCode: 400, errMsg: Current service DEFAULT_GROUP@@product-service is
 ephemeral service, can't register persistent instance. ;
 at 
com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(Naming
HttpClientProxy.java:410) ~[nacos-client-2.2.1.jar:na]
 at 
com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(Naming
HttpClientProxy.java:351) ~[nacos-client-2.2.1.jar:na]
 at 
com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(Naming
HttpClientProxy.java:346) ~[nacos-client-2.2.1.jar:na]

原因: Nacos会记录每个服务实例的IP和端⼝号, 当发现IP和端⼝都没有发⽣变化时, Nacos不允许⼀个服务实例类型发⽣变化, ⽐如从临时实例,变为⾮临时实例, 或者从⾮临时实例, 变成临时实例.

解决办法:

1. 停掉nacos

2. 删除nacos ⽬录下 /data/protocol/raft 信息, ⾥⾯会保存应⽤实例的元数据信息.

5.3.2 服务正常, Nacos健康检查失败

现象:

服务正常, 但是Nacos显⽰健康状态为false

原因和解决办法:

参考:

如何解决Nacos持久化实例HTTP/TCP的健康检查不通过问题_微服务引擎(MSE)-阿⾥云帮助中⼼

6. Nacos环境隔离

企业开发中, ⼀个服务会分为开发环境, 测试环境和⽣产环境.

1. 开发环境:开发⼈员⽤于开发的服务器, 是最基础的环境. ⼀般⽇志级别设置较低, 可能会开启⼀些调试信息.

2. 测试环境:测试⼈员⽤来进⾏测试的服务器, 是开发环境到⽣产环境的过渡环境.

3. ⽣产环境:正式提供对外服务的环境, 通常关掉调试信息.

通常情况下, 这⼏个环境是不能互相通信的. Nacos提供了namespace(命名空间)来实现环境的隔离. 不同的namaspace的服务不可⻅.

6.1 创建Namespace

默认情况下,所有服务都在同一个namespace,名为piblic

点击左侧命名空间, 可以对namespace进⾏操作

新增命名空间

6.2 配置Namespace

namespace创建完成后, 对服务进⾏配置

配置项 Key 默认值

说明

命名空间

spring.cloud.nacos.discovery.namespace

常⽤场景之⼀是不同环境的注册的区分隔离,例如开发测试环境和⽣产环境的资源(如配置、服务)隔离等。

修改order-service的命名空间

spring:
  cloud:
    nacos:
      discovery:
        namespace: 51152a13-7911-49e3-bbdc-16fd5670a257

6.3 测试远程调用

1. 启动服务, 观察Nacos控制台

public 命名空间下只有product-service服务

order-service在dev命名空间下

2. 访问接⼝, 测试远程调⽤

发现服务报错:

2023-12-27T18:23:27.058+08:00 ERROR 30408 --- [nio-8080-exec-1] o.a.c.c.C.[.[.
[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] 
in context with path [] threw exception [Request processing failed: 
java.lang.IllegalStateException: No instances available for product-service] 
with root cause

java.lang.IllegalStateException: No instances available for product-service
 at 
org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClie
nt.execute(BlockingLoadBalancerClient.java:78) ~[spring-cloud-loadbalancer-
4.0.3.jar:4.0.3]
 at 
org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept
(LoadBalancerInterceptor.java:56) ~[spring-cloud-commons-4.0.3.jar:4.0.3]
 at 
org.springframework.http.client.InterceptingClientHttpRequest$InterceptingReque
stExecution.execute(InterceptingClientHttpRequest.java:87) ~[spring-web-
6.0.14.jar:6.0.14]
 at 
org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(I
nterceptingClientHttpRequest.java:71) ~[spring-web-6.0.14.jar:6.0.14]
 at 
org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInter
nal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-6.0.14.jar:6.0.14]
 at 
org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClien
tHttpRequest.java:66) ~[spring-web-6.0.14.jar:6.0.14]
 at 
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:862) ~
[spring-web-6.0.14.jar:6.0.14]
 // ...

3. 修改product-service的其中⼀个实例, 命名空间改为dev

spring:
  cloud:
    nacos:
      discovery:
        namespace: 51152a13-7911-49e3-bbdc-16fd5670a257

4. 启动服务

观察Nacos控制台

再次访问接⼝ http://127.0.0.1:8080/order/3, 发现远程调⽤成功

7. Nacos配置中心

除了注册中⼼和负载均衡之外, Nacos还是⼀个配置中⼼, 具备配置管理的功能.

Namespace 的常⽤场景之⼀是不同环境的配置区分隔离. 例如开发测试环境和⽣产环境的配置隔离.

7.1 为什么需要配置中心

当前项⽬的配置都在代码中, 会存在以下问题:

1. 配置⽂件修改时, 服务需要重新部署. 微服务架构中, ⼀个服务可能有成百个实例, 挨个部署⽐较⿇烦, 且容易出错.

2. 多⼈开发时, 配置⽂件可能需要经常修改, 使⽤同⼀个配置⽂件容易冲突.

配置中⼼就是对这些配置项进⾏统⼀管理. 通过配置中⼼, 可以集中查看, 修改和删除配置, ⽆需再逐个修改配置⽂件. 提⾼效率的同时, 也降低了出错的⻛险.

1. 服务启动时, 从配置中⼼读取配置项的内容, 进⾏初始化.

2. 配置项修改时, 通知微服务, 实现配置的更新加载.

7.2 快速上手

通过以下操作, 我们先来感受下Nacos 配置中⼼的使⽤

参考⽂档: Nacos Spring Cloud 快速开始 Nacos config

7.2.1 添加配置

在Nacos控制台添加配置项

💡 注意: 配置管理的命名空间和服务列表的命名空间是隔离的, 两个是分别设置的. 默认是public 也就是服务管理命名空间配置 ≠ 配置管理的命名空间

新建配置项

配置内容:

nacos.test.num=5

说明:

1. Data ID 设置为项⽬名称

2. 配置内容的数据格式, ⽬前只⽀持 properties 和 yaml 类型

3. 设置配置内容

7.2.2 获取配置

1. 引入Nacos Config依赖
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>
 <!-- SpringCloud 2020.*之后版本需要引⼊bootstrap-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-bootstrap</artifactId>
 </dependency>
2.配置bootstrap properties

微服务启动前, 需要先获取nacos中配置, 并与application.yml配置合并. 在微服务运⾏之前, Nacos要求必须使⽤ bootstrap.properties 配置⽂件来配置Nacos Server 地址.

spring.application.name=product-service
spring.cloud.nacos.config.server-addr=110.41.51.65:10020

或者使用bootstrap.yml

spring:
 application:
   name: product-service
 cloud:
   nacos:
    config:
      server-addr: 110.41.51.65:10020

spring.application.name 需要和nacos配置管理的Data ID⼀致spring.cloud.nacos.config.server-addr 为Nacos Server的地址

💡 配置中⼼和注册中⼼的配置是隔离的

Nacos 配置中⼼: spring.cloud.nacos.config.server-addr

Nacos 注册中⼼: spring.cloud.nacos.discovery.server-addr

3. 编写程序
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;

 @RequestMapping("/config")
 @RefreshScope
 @RestController
 public class NacosController {
     @Value("${nacos.test.num:0}")
     private Integer nacosNum;

     @RequestMapping("/get")
     public Integer get() {
     return nacosNum;
     }
 }

• @Value 读取配置

• @RefreshScope 配置进⾏热更新

4. 测试

启动程序, 访问接⼝: http://127.0.0.1:9090/config/get

在Nacos控制台修改 nacos.test.num

再次访问接口:

7.2.3 常见问题

1. 读取不到配置项

可能原因:◦ 配置错误: 检查配置Data ID, 配置格式, 配置空间等

◦ 未引⼊依赖

2. No spring.config.import property has been defined

启动报错⽇志:

 ***************************
 APPLICATION FAILED TO START
 ***************************

 Description:

 No spring.config.import property has been defined

 Action:

 Add a spring.config.import=nacos: property to your configuration.
     If configuration is not required add 
spring.config.import=optional:nacos: instead.
     To disable this check, set spring.cloud.nacos.config.importcheck.enabled=false.

原因: bootstrap.properties 是系统级的资源配置⽂件, ⽤于程序执⾏更加早期配置信息读取. 但是SpringCloud 2020.* 之后的版本把bootstrap禁⽤了, 导致在读取⽂件的时候读取不到⽽报错, 所以需要重新导⼊bootstrap 包进来就可以了

3. Nacos Server地址配置错误

报错信息如下:

2023-12-28T17:12:53.070+08:00 ERROR 14356 --- [t.remote.worker] 
c.a.n.c.remote.client.grpc.GrpcClient : Server check fail, please check 
server 127.0.0.1 ,port 11020 is available , error ={}

 java.util.concurrent.ExecutionException: 
com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: io
exception
 at 
com.alibaba.nacos.shaded.com.google.common.util.concurrent.AbstractFuture.ge
tDoneValue(AbstractFuture.java:566) ~[nacos-client-2.2.1.jar:na]
 at 
com.alibaba.nacos.shaded.com.google.common.util.concurrent.AbstractFuture.ge
t(AbstractFuture.java:445) ~[nacos-client-2.2.1.jar:na]
 // ...
 
 Caused by: com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException:
UNAVAILABLE: io exception
 at 
com.alibaba.nacos.shaded.io.grpc.Status.asRuntimeException(Status.java:539) 
~[nacos-client-2.2.1.jar:na]
 at 
com.alibaba.nacos.shaded.io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClos
e(ClientCalls.java:544) ~[nacos-client-2.2.1.jar:na]
 at 
com.alibaba.nacos.shaded.io.grpc.internal.DelayedClientCall$DelayedListener$
3.run(DelayedClientCall.java:471) ~[nacos-client-2.2.1.jar:na]

 // ...
 Caused by: 
com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.AbstractChann
el$AnnotatedConnectException: Connection refused: no further information: 
/127.0.0.1:11020
 Caused by: java.net.ConnectException: Connection refused: no further
information
 at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
 at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
 at 
java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:
946) ~[na:na]

7.3 配置中心详解

7.3.1 设置命名空间

Nacos配置管理的命名空间和服务列表的命名空间是分别设置的. 默认是public

Nacos命名空间配置依然在bootstrap.properties中进⾏配置

spring.cloud.nacos.config.namespace=51152a13-7911-49e3-bbdc-16fd5670a257

对应bootstrap.yml配置

spring:
 cloud:
   nacos:
     config:
       namespace: 51152a13-7911-49e3-bbdc-16fd5670a257

value对应 命名空间的ID, 如下图所⽰:

如果设置命名空间后, 项⽬启动时, 会从该命名空间下找对应的配置项.

重新访问接⼝, 观察结果:

http://127.0.0.1:9090/config/get

7.3.2 Data Id

Data Id 格式介绍

在 Nacos Spring Cloud 中, dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值, 也可以通过配置项spring.cloud.nacos.config.prefix 来配置.
  • spring.profiles.active 即为当前环境对应的 profile. 当 spring.profiles.active为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。⽬前只⽀持 properties和 yaml 类型. 默认为properties.

微服务启动时, 会从Nacos读取多个配置⽂件:

  1. ${prefix}-${spring.profiles.active}.${file-extension} 如: product-service-dev.properties
  2. ${prefix}.${file-extension} , 如: product-service.properties
  3. ${prefix} 如product-service

💡 ${spring.application.name}, ${spring.profiles.active} 等通过配置⽂件来指定时, 必须放在bootstrap.properties ⽂件中

观察⽇志

在bootstrap.yml中添加 spring.profiles.active 值

spring:
  profiles:
    active: dev

启动服务,观察日志

2023-12-28T18:48:08.614+08:00 INFO 36672 --- [ main] 
c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [subscribe] product-servicedev.properties+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
2023-12-28T18:48:08.624+08:00 INFO 36672 --- [ main] 
c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-
bbdc-16fd5670a257, dataId=product-service-dev.properties, group=DEFAULT_GROUP, 
cnt=1
2023-12-28T18:48:08.624+08:00 INFO 36672 --- [ main] 
c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: 
dataId=product-service-dev.properties, group=DEFAULT_GROUP
2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] 
c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [subscribe] productservice.properties+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] 
c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-
bbdc-16fd5670a257, dataId=product-service.properties, group=DEFAULT_GROUP, 
cnt=1
2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] 
c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: 
dataId=product-service.properties, group=DEFAULT_GROUP
2023-12-28T18:48:08.626+08:00 INFO 36672 --- [ main] 
c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [subscribe] productservice+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
2023-12-28T18:48:08.627+08:00 INFO 36672 --- [ main] 
c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-
16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-
bbdc-16fd5670a257, dataId=product-service, group=DEFAULT_GROUP, cnt=1
2023-12-28T18:48:08.627+08:00 INFO 36672 --- [ main] 
c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: 
dataId=product-service, group=DEFAULT_GROUP

三个⽂件的优先级为: product-service-dev.properties > product-service.properties > product-service

测试

bootstrap.yml配置如下:

spring:
  application:
    name: product-service
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        server-addr: 110.41.51.65:10020
        namespace: 51152a13-7911-49e3-bbdc-16fd5670a257

配置项如下:

访问接⼝: http://127.0.0.1:9090/config/get

服务获取到了 product-service-dev.properties 的值

删除 product-service-dev.properties 配置, 再次访问接⼝

💡 注意:

1. bootstrap.yml 设置的配置格式必须和nacos控制台配置的数据格式保持⼀致.

2. 不设置配置格式(spring.cloud.nacos.config.file-extension)时, 默认为properties

8. 服务部署

1. 修改数据库, Nacos等相关配置

2. 对两个服务进⾏打包

3. 上传jar到Linux服务器

4. 启动Nacos

        启动前最好把data数据删除掉.

5. 启动服务

#后台启动order-service, 并设置输出⽇志到logs/order.log
 nohup java -jar order-service.jar >logs/order.log &

 #后台启动product-service, 并设置输出⽇志到logs/order.log
 nohup java -jar product-service.jar >logs/product-9090.log &

 #启动实例, 指定端⼝号为9091
 nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &

观察Nacos控制台

6. 测试

访问接⼝: http://110.41.51.65:8080/order/1

观察远程调⽤的结果:

9. Nacos与Eureka的区别

共同点:

• 都⽀持服务注册和服务拉取

区别:

1. 功能

        Nacos除了服务发现和注册之外, 还提供了配置中⼼, 流量管理和DNS服务等功能.

2. CAP理论

        Eureka遵循AP原则, Nacos可以切换AP和CP模式,默认AP.

        Nacos 根据配置识别CP或者AP模式. 如果注册Nacos的Client的节点是临时节点, 那么Nacos对这个Client节点的效果就是AP, 反之是CP. AP和CP可以同时混合存在.

3. 服务发现

        Eureka:基于拉模式. Eureka Client会定期从Server拉取服务信息, 有缓存, 默认每30秒拉取⼀次.

        Nacos:基于推送模式. 服务列表有变化时实时推送给订阅者, 服务端和客⼾端保持⼼跳连接.

        服务启动:

        服务停止:

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐