Nacos

发布时间 2023-08-11 16:07:30作者: 江南烟雨行舟

就是专门用来做:

  • 注册中心: 就是避免增删服务时,修改配置文件。

    它又包含服务注册:服务提供者,启动的时候向注册中心上报自己的网络信息;服务发现:服务消费者,启动的时候向注册中心上报自己的网络信息,还会拉取服务提供者的相关网络信息

  • 配置中心: 就是动态更新服务的配置文件。

    把一些统一的配置(数据库配置)放到配置中心,当服务启动的时候会从配置中心获取配置。

  • 元数据: 就是服务的一些自定义属性。

nacos-stru.drawio2

Docker 运行

下面是一个最简单的命令,用来做本地测试的:

$ docker run -d -e PREFER_HOST_MODE=hostname -e MODE=standalone -p "8848:8848" -p "9848:9848" nacos/nacos-server:v2.2.0-slim

项目配置

<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>
    </dependency>
    
    <!-- 动态外部化配置 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
</dependencies>

bootstrap.yaml 文件的配置,这个配置文件优先于 application.yaml 加载:

spring:
  application:
    # 服务名称
    name: 
  cloud:
    nacos:
      discovery:
        # Nacos ip:port
        server-addr:

@EnableDiscoveryClient 注解可以不用了,因为 Spring Boot 会自动配置,保证服务启动后会自动注册到 Nacos。

服务注册中心

在 spring-cloud-starter-alibaba-nacos-discovery 启动器里面有一个 NacosServiceRegistryAutoConfiguration 类,[Spring Boot 启动](../Spring Boot/自动装配原理&启动流程.md)的时候会通过这个自动配置类创建 NacosServiceRegistry 实例,这个实例最终会委托给 NamingGrpcClientProxy#registerService 方法注册服务。

可以使用 DiscoveryClient、Loadbalancer 调用服务,使用 Nacos 自带的 NacosLoadBalancer:

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

public class NacosLoadBalancerConfiguration {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> nacosLoadBalancer(Environment environment,
                                                                  LoadBalancerClientFactory loadBalancerClientFactory,
                                                                  NacosDiscoveryProperties nacosDiscoveryProperties) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
    }
}

下面是常用的一些配置:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: # ip:port
        username: # 鉴权,用户名
        password: # 鉴权,密码
        logName: # 日志名称
        # 目前从 Spring Cloud 客户端和 Dubbo 客户端都没有打通, 所以不能生效.
        # 对于 Spring Cloud 客户端, 应用可以实现 Ribbon 的负载均衡器来进行权重过滤.
        weight: 1 # 服务实例的权重,值越大权重越大。
        clusterName: # 集群名称
        # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
        namespace: ba42e722-81aa-48f1-9944-9dca57d5f396
        group: # 可以理解为某个项目中的某个服务,它和 namespace 没有指定格式,按照自己的理解配置
        metadata: # 服务注册时的自定义数据
          k1: v1

服务配置中心

使用 bootstrap.yaml 配置文件来配置:

spring:
  application:
    name: nacos-config
  cloud:
    nacos:
      config:
        server-addr: 192.168.112.128:8848
        file-extension: yaml
        group: dev
        namespace: 

从配置中心拉取下来的配置都是保存在 Spring Environment 中,默认情况是支持动态刷新的,但是可以通过 spring.cloud.nacos.config.refresh.enabled=false 关闭动态刷新。

下面是常用的一些配置:
spring.cloud.nacos.config.shared-configs[0].data-id=shared-redis.properties
spring.cloud.nacos.config.shared-configs[0].group=dev
spring.cloud.nacos.config.shared-configs[0].refresh=false

不同级别的配置

通过 DataId 从配置中心获取或监听配置文件,DataId 有二种配置格式,客户端只会获取或监听一个满足格式的文件:

${spring.application.name}-${profile}.${file-extension:properties}
${spring.application.name}.${file-extension:properties}

${profile} 对应的就是下面这个配置,这个配置不存在第一种 DataId 格式也不会存在:

spring:
  profiles:
    active: product

自定义命名空间

每个命名空间中可以有多个组,每个组中又可以有多个 DataId;命名空间可以理解为 Java 中的包。

如果 bootstrap.yaml 配置文件中没有指定 namespace,则会使用 Nacos 自带的 "Public" 命名空间:

spring:
  cloud:
    nacos:
      config:
        namespace: b3404bc0-d7dc-4855-b519-570ed34b62d7

如果 bootstrap.yaml 配置文件中没有指定 spring.cloud.nacos.config.group,默认使用 DEFAULT_GROUP:

spring:
  cloud:
    nacos:
      config:
        group: DEVELOP_GROUP

获取或监听多个 DataId:

spring:
  cloud:
    nacos:
      config:
        extension-configs:
          -
            dataId: ssss.yaml
            group: DEFAULT_GROUP
            refresh: true
          -
            dataId: 111.yaml

参考资料

Nacos架构&原理.pdf

微服务开发指南.pdf