Nacos

文章目录

Nacos

1. Nacos介绍

在Eureka2.0 宣布闭源的同年,阿里Nacos宣布开源,快速成为了国内最受关注的开源产品

在最初开源的时候,Nacos选择进行内部三个产品合并统一开源(Configserver非持久注册中心,VIPServer持久化注册中心,Diamond配置中心),定位为一个易于构建云原生应用的动态服务实现,配置管理和服务管理平台,所以Nacos是一个注册中心组件,但是又不仅仅是一个注册中心组件

2. Nacos安装

2.1 windows安装

下载安装包

目前官方推荐的就是稳定版本2.2.3

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

目录介绍
  • bin:Nacos启停脚本
    • startup.cmd:windows平台的启动脚本
    • startup.sh:Linux平台的启动脚本
    • shutdown.cmd:windows平台停止脚本
    • shutdown.sh:Linux平台的停止脚本
  • conf:Nacos配置文件
  • target:存放Nacos应用的jar包
修改单机模式

直接启动会报错

java 复制代码
Caused by: java.net.UnknownHostException: jmenv.tbsite.net

这是因为Nacos默认是集群(cluster)启动 ,将其设置为单机(standalone),设置方式为

  1. 用记事本打开startup.cmd
  2. 修改

修改为<font style="color:rgb(100,106,115);">set MODE="standalone"</font>

通过http://127.0.0.1/8848/nacos访问Nacos主页

端口号冲突解决方法

Nacos默认端口号是8848,如果该端口号被占用,启动就会报错

解决方法为:

  1. 关闭原有的8848端口号的进程
    1. 在cmd输入命令netstat -ano|findstr "8848"
    2. 杀掉进程,输入命令taskkill /pid 4968 /f
  2. 修改Nacos端口号

修改位置为 ${Nacos目录}/conf/application.properties

2.2 Linux环境安装

上传安装包
解压
java 复制代码
unzip nacos-server-2.2.3.zip

如果出现

需要先安装unzip

java 复制代码
apt-get install unzip

解压完后目录如下

单机模式启动
java 复制代码
cd nacos/bin/
bash startup.sh -m standalone

注意:nacos启动前需要安装JDK

3. Nacos快速上手

与Eureka的区别主要是,Eureka需要自己搭建一个服务,Nacos不用自己搭建服务,组件已经准备好了,只需启动即可

2.1 服务注册/服务发现

引入依赖

在父工程的pom文件中引入

注意:Spring Cloud Alibaba的依赖要在<font style="color:rgb(31,35,41);"><dependencyManagement></font>中引入,确保与SpringBoot版本匹配。

xml 复制代码
<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>
引入Nacos依赖

在order-service以及product-service中引入nacos依赖

xml 复制代码
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

引入Load Balance依赖

xml 复制代码
<dependency> 
   <groupId>org.springframework.cloud</groupId> 
   <artifactId>spring-cloud-loadbalancer</artifactId> 
</dependency>
配置Nacos的地址
yaml 复制代码
spring:
  application:
    name: product-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
添加负载均衡注解
java 复制代码
@Configuration
public class BeanConfig {
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
远程调用
java 复制代码
@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public  OrderInfo getOrderList(int orderId){
        OrderInfo orderInfo = orderMapper.getOrderList(orderId);
        String url = "http://product-service/product/getProduct?productId=" + orderInfo.getProductId();
        log.info(url);
        ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}
启动两个服务
启动多个服务,测试负载均衡

4. Nacos 负载均衡

Nacos支持多种负载均衡策略,包括权重,同机房,同地域,同环境等

4.1 服务下线

当某一个节点性能比较差的时候,我们可以第一时间对该节点进行下线

此时这个服务就不能处理请求了

4.2 权重配置

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

配置权重
开启Nacos负载均衡策略

由于Spring Cloud LoadBalance组件自身有负载均衡配置方式,所以不支持Nacos的权重属性配置

我们需要开启Nacos的负载均衡策略,让权重配置生效

yaml 复制代码
spring: 
  cloud: 
    loadbalancer: 
      nacos: 
        enabled: true
测试

发生20次请求

4.3 同集群优先访问

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

微服务架构里,一个服务通常有多个实例共同提供服务,这些实例可以部署在不同的机器上,这些机器可以分布在不同的机房

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

给实例配置集群名称
  1. 为product-service配置集群名称
yaml 复制代码
spring:
 cloud:
   nacos:
     discovery:
       cluster-name: SH
  1. 设置9090端口号的produc-service机房为BJ
  2. 设置order-service的集群为BJ
yaml 复制代码
spring:
  cloud:
    nacos:
      discovery:
        cluster-name: BJ
  1. 重启全部服务:
  1. 此时访问接口

发现只有端口号为9090的服务处理请求,因为集群是BJ

5. Nacos健康检查

5.1 两种健康检查机制

Nacos作为注册中心,需要感知服务的健康状态,才能为服务调用方提供良好的服务

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

客户端主动上报机制

即客户端会通过心跳上报方式告服务端(nacos注册中心)健康状态,默认心跳间隔5s

nacos会在超过15s后未收到心跳将实例设置为不健康的状态,超过30s将实例删除

服务端反向探测机制

nacos主动探知客户端健康状态,默认间隔时间为20s

健康状态失败后实例会被标记为不健康,不会被立即删除

值得注意的是,nacos中的健康检查机制不能修改,它是和Nacos的服务实例类型强相关的

5.2 Nacos服务实例类型

Nacos的服务实例分为临时实例和非临时实例

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

Nacos对临时实例,采取的是 客户端主动上报机制; 对于临时实例,则采取服务端反向探测机制

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

```yaml spring: cloud: nacos: discovery: ephemeral: false ```

重启服务,观察控制台

发现报错:

原因:Nacos会记录每个服务实例的IP和端口号,当发现IP和端口号都没有变化时,Nacos不允许一个服务实例发生变化,比如从临时实例,变为非临时实例,或者从非临时实例,变为临时实例

解决方法为

  1. 停掉Nacos
  2. 删除nacos目录下 /data/protocol/raft信息
停止节点

![](https://img-blog.csdnimg.cn/img_convert/8706e061bebf92efb2db51dd2a8e954e.png)

节点仍然不会消失

6. Nacos环境隔离

通常在企业开发中,一个服务会被分成开发环境,测试环境和生产环境

通常情况下这几种环境是不能互通的,Nacos提供了namespace命名空间来实现环境的隔离,不同的namespace的服务不可见

创建Namespace

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

可以新增命名空间

修改order-service的命名空间

yaml 复制代码
spring:
  cloud:
    nacos:
      discovery:
        namespace: 023008c1-7b07-4ea8-9916-0218e873f0ab

测试命名空间

重启order-service

此时再通过接口访问,就会报错

我们修改product-service的命名空间为dev

重启9090的服务

此时就可以访问了,但是只能访问9090的服务

7. Nacos配置中心

7.1 配置中心的作用

我们当前的项目配置都在代码里面,如果配置文件需要修改的话,服务需要重新部署,其次,多人开发的时候,配置文件可能需要经常修改,使用一个配置文件容易发生冲突

配置中心就是单对这些配置项进行统一的管理,通过配置中心,可以集中查看,修改和删除配置,无需再逐个修改配置文件. 提高效率的同时,也降低了出错的风险

  1. 当服务启动的时候,从配置中心读取配置项的内容,进行初始化
  2. 配置项修改时,通知微服务,实现配置的更新加载

7.2 快速上手

添加配置

在Nacos控制台添加配置

注意:

  1. 配置管理的命名空间和服务列表的命名空间是隔离的,两个是分开来设置的. 默认是public,也就是服务管理命名空间 ≠ 配置管理命名空间
  2. Data ID设置为项目名称
  3. 配置内容的数据格式,只支持propertiesyaml类型
获取配置
引入Nacos Config依赖

```xml com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config org.springframework.cloud spring-cloud-starter-bootstrap ```

配置bootstrap.properties

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

properties 复制代码
spring.application.name=product-service
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

注意:

  1. 这里的spring.application.name需要与nacos里面的Data ID一致
  2. 配置中心和注册中心的配置是隔离的
编写代码

```java @RestController @RefreshScope // 配置修改后,同步修改 @RequestMapping("nacos") public class NacosController { @Value("${nacos.test.num}") private Integer num;

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

}

![](https://cdn.nlark.com/yuque/0/2024/png/44161339/1727785771147-7525bc98-7c6c-441f-a7d3-2fe80a4a9346.png)

### 7.3 配置中心详解
<h4 id="p2w8Z">设置命名空间</h4>
Nacos配置管理的命名空间和服务列表的命名空间是分开设置的,默认是public

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

```properties
spring.cloud.nacos.config.namespace=1b0187df-3aff-4cd7-ad44-8a9b99ec8d23

其中value对应的是

此时重新访问接口:

得到的是prod命名空间下的配置

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-extension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置。目前只支持propertiesyaml类型,默认为properties

我们在bootstrap.properties添加spring.profiles.active的值

properties 复制代码
spring.profiles.active=dev

启动项目,观察日志

微服务启动时, 会从Nacos读取多个配置⽂件,三者的优先级是

<font style="color:rgb(31,35,41);">product-service-dev.properties > product-service.properties > product-service</font>

测试

bootstrap.properties配置

properties 复制代码
spring.application.name=product-service
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=1b0187df-3aff-4cd7-ad44-8a9b99ec8d23
spring.profiles.active=prod

创建3个配置

访问接口:

删除配置<font style="color:rgb(51, 51, 51);background-color:rgb(245, 247, 249);">product-service-prod.properties</font>,再次访问

8. Nacos和Eureka的区别

功能

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

CAP理论

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

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

服务发现

Eureka:基于拉模式,Eureka CLient会定期从Server拉取服务信息,有缓存,默认30s拉取一次

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

相关推荐
捂月8 分钟前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
瓜牛_gn34 分钟前
依赖注入注解
java·后端·spring
Estar.Lee1 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
喜欢猪猪1 小时前
Django:从入门到精通
后端·python·django
一个小坑货1 小时前
Cargo Rust 的包管理器
开发语言·后端·rust
bluebonnet271 小时前
【Rust练习】22.HashMap
开发语言·后端·rust
uhakadotcom1 小时前
如何实现一个基于CLI终端的AI 聊天机器人?
后端
一元咖啡2 小时前
SpringCloud Gateway转发请求到同一个服务的不同端口
spring·spring cloud·gateway
Iced_Sheep2 小时前
干掉 if else 之策略模式
后端·设计模式