Nacos

目录

概述

Nacos 是一个更易于构建云原生应用的动态服务发现配置管理服务管理平台注册中心+ 配置中心 + 总线)。

Nacos 是 Naming 、Configuration、Service 这三个单词拼凑而来。

官网:https://github.com/alibaba/Nacos

https://nacos.io/zh-cn/

安装下载

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

注意:2.2.1 以后需要 将 Nacos/conf/application.properties 文件添加默认 key,指定规则:自定义密钥时,推荐将配置项设置为**Base64编码 **的字符串,且原始密钥长度不得低于32字符。

使用单机模式启动

bin/startup.sh -m standalone

看到如下界面表示启动成功。

通过下边的网址登录管理界面:http://192.168.3.104:8848/nacos/index.html

默认账号密码均为 :nacos

服务注册

官网:https://spring.io/

服务提供者

新增 mvn 依赖

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

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

配置信息

spring:
  application:
  	# 微服务名称
    name: nacos-payment-provider
  cloud:
    nacos:
     # 服务注册地址
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'

服务启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
// 发现服务
@EnableDiscoveryClient
public class PaymentMain9001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain9001.class, args);
    }
}

服务消费者

Nacos 支持负载均衡。Nacos 自带 ribbon,ribbon 是做负载均衡的 jar 包。

新增 mvn 依赖

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

配置信息

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.3.104:8848


#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

服务启动类

@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerMain83 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerMain83.class, args);
    }
}

配置类

@Configuration
public class ApplicationContextBean {
    @Bean
  	// 负载均衡(必须)
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

Controller

@RestController
public class ConsumerController {

    @Value("${service-url.nacos-user-service}")
    private String serverUrl;

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "/consumer/nacos/{id}")
    public String get(@PathVariable("id") int id) {
        return restTemplate.getForObject(serverUrl + "/payment/nacos/" + id, String.class);
    }
}

注册中心对比

  Nacos Eureka Consul CoreDNS Zookeeper
一致性协议 CP + AP AP CP / CP
健康检查 TCP/HTTP/MySQL/Client Beat Client Beat TCP/HTTP/GRPC/Cmd / Client Beat
负载均衡 权重/DSL/metadata/CMDB Ribbon Fabio RR /
雪崩保护 支持 支持 不支持 不支持 不支持
自动注销实例 支持 支持 不支持 不支持 支持
访问协议 HTTP/DNS/UDP HTTP HTTP/DNS DNS TCP
监听支持 支持 支持 支持 不支持 支持
多数据中心 支持 支持 支持 不支持 不支持
夸注册中心 支持 不支持 支持 不支持 不支持
SpringCloud 集成 支持 支持 支持 不支持 不支持
Dubbo 集成 支持 不支持 不支持 不支持 支持
K8s 集成 支持 不支持 支持 支持 不支持

Nacos 支持 AP 和 CP 模式的切换。

  • C - Consistent,一致性:all nodes see the same data at the same time,即所有节点在同一时间的数据完全一致。
  • A - Availability,可用性:Reads and writes always succeed,即服务在正常响应时间内一直可用。
  • P - Partition tolerance,分区容忍性:the system continues to operate despite arbitrary message loss or failure of part of the system。即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。

如果不需要存储服务级别的信息且服务实例是通过 nacos-client 注册,并能够保持心跳上报,那么就可以选择 AP 模式。当前主流的服务如:Spring cloud 和 Dubbo 服务,都适用于 AP 模式,AP 模式为了服务的可能性而减弱了一致性,因此 AP 模式下值支持注册临时实例

如果需要在服务级别编辑或者存储配置信息,那么 PC 是必须,K8S 服务和 DNS 服务则适用于 PC 模式。

CP 模式

下则支持注册持久化实例,此时则是使用以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会报错。

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

配置中心

项目搭建

新增 mvn 依赖

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

Nacos 同 Springcloud-config 一样,在项目初始化时,先从配置中心进行配置拉去,再去启动项目。

SpringBoot 中配置文件的加载优先级:bootstrap 优先级高于 application

bootstrap.yml

# nacos配置
server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.3.104:8848 #Nacos服务注册中心地址
      config:
        server-addr: 192.168.3.104:8848 #Nacos作为配置中心地址
        file-extension: yaml #指定yaml格式的配置

application.yml

spring:
  profiles:
    active: dev # 表示开发环境

服务启动类

@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
    public static void main(String[] args) {
        SpringApplication.run(NacosConfigClientMain3377.class, args);
    }
} 

业务类

@RestController
@RefreshScope // 支持 Nacos 的动态刷新
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

数据配置

dataId 的完整格式如下

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix:默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active:即为当前环境对应的 profile。
  • file-extension:为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

例子:根据下边的 yaml 文件的内容,对应的 dataId = nacos-config-client-dev.yaml

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.3.104:8848 #Nacos服务注册中心地址
      config:
        server-addr: 192.168.3.104:8848 #Nacos作为配置中心地址
        file-extension: yaml #指定yaml格式的配置
        
        
spring:
  profiles:
    active: dev # 表示开发环境        

新增一条测试数据

动态更新

在 nacos 中修改配置数据,线上立即收到最新的数据。

分类配置

问题

实际开发过程中,通常一个系统有多个环境:

  • dev 开发环境
  • rc 准生产环境
  • prod 生产环境

如何保证不同的环境读取不同的配置数据呢?

通过 Namespace、Group、DataID 实现配置数据的隔离。

类似 Java 里面的 package 名。

namespace 用于区分部署环境,Group 和 DataID 逻辑上区分不同的目标对象。

默认情况:NameSpace = public,Group = DEFAULT_GROUP、默认 Cluster 是 DEFAULT

Group 可以把不同的微服务划分到同一个分组里。

方案一:DataID

Namespace、Group 使用默认值,不同环境使用不同的 DataID 来区分不同的环境。

不同开发环境加载不同的 yaml 文件

spring:
  profiles:
    active: rc # 表示开发环境       

方案二:Group

Namespace 使用默认值,DataID 相同,不同环境使用不同的 Group 来区分不同的环境。

需要再 spring.cloud.nacos.config 下配置 group

方案三:Namespace

新增不同的 Namespace,将命名空间 ID 配置到项目中 yaml 中。

需要再 spring.cloud.nacos.config 下配置 namespace

Nacos 集群

默认 Nacos 使用嵌入式数据库(derby)实现数据存储。如果启动多个默认配置下的 Nacos 节点,数据存储是存在一致性的问题。

为了解决这个问题,Nacos 采用了集中式存储的方式来支持集群化部署,支持 MySQL 的存储。

Nacos 支持三种部署模式

  • 单机模式:用于测试和单机试用。
  • 集群模式:用于生产环境,确保高可用。
  • 多集群模式:用于多数据中心场景。

配置 MySQL

创建数据库

create database nacos_config;
use nacos_config;

创建表:nacos/conf/mysql-schema.sql

修改 Nacos 配置 nacos/conf/application.properties

spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456

如下图,之后在 Nacos 中添加的配置数据就保存在我们自己的 MySQL 数据库中了。

配置 Nacos 集群

配置集群 IP :nacos/conf/cluster.conf

192.168.3.104:3333
192.168.3.104:4444
192.168.3.104:5555
注意:在一台机器上部署nacos集群时,不能将运行端口设置为连续端口,比如8841、8842、8843,否则会发生端口冲突。

拷贝出三份 nacos 文件:

分别修改启动的端口: conf/application.properties

最后逐一启动

bin/startup.sh

配置 Nginx

修改 /usr/local/etc/nginx/nginx.conf 文件

启动 Nginx

./nginx -c /usr/local/etc/nginx/nginx.conf

修改服务yaml 中配置的 nacos 地址为 nginx 的地址

通过 nginx 地址访问 nacos

小结

上述 nacos 集群的架构图