初识nacos

333 阅读6分钟

一、nacos的基本概念

nacos的服务模型如下:

image.png

Nacos 服务发现使用的领域模型是命名空间-分组-服务-集群-实例这样的多层结构,服务 Service 和实例 Instance 是核心模型,命名空间 Namespace 、分组 Group、集群 Cluster 则是在不同粒度实现了服务的隔离。

命名空间(应用环境隔离)

命名空间(Namespace):Nacos 服务中最顶层、也是包含范围最广的概念,用于强制隔离类似环境或租户等场景;Nacos 的服务也需要使用命名空间来进行隔离。命名空间的默认值是public在 Nacos 中通过命名空间(Namespace)+ 分组(Group)+ 服务名(Name)可以定位到一个唯一的服务实例

image.png

为项目配置命令空间:

spring.cloud.nacos.discovery.namespace=name

命名空间配置:

image.png

分组名(环境|使用场景)

分组名(Group)是Nacos 中次于命名空间的隔离概念,区别于命名空间的强制隔离属性,分组属于个弱隔离概念,主要用于逻辑区分些服务使用场景或不同应用的同名服务,最常用的情况主要是同个服务的测试分组和生产分组、或者将应用名作为分组以防止不同应用提供的服务重名。

image.png

为项目配置分组名:

spring.cloud.nacos.discovery.group=name

服务名

表示该服务实际的名字,般用于描述该服务提供了某种功能或能力。

在项目中的配置:

spring.application.name=simtek-cosimcloud-fmu

集群(Cluster)

加入Nacos的注册中心,如果服务名一致的服务会自动配置为集群:

image.png

image.png 如上所示,可以通过编辑配置权重。

保护阈值

保护阈值可以设置为0-1之间的浮点数(当前服务健康实例数/当前服务总实例数)

  • 当健康实例数占总服务实例数的比例小于该值时,无论实例是否健康,nacos将会把该服务所有的实例信息(健康的+不健康的)全部提供给消费者;
  • 消费者可能访问到不健康的实例,导致请求失败,但也避免了流量压力将剩余实例被压垮形成雪崩效应
  • 最终,保证了整个系统的可用性。

服务路由类型

image.png

如果设置此值为 label(标签)模式,需要设置相应的标签表达式来匹配实例选择器(Selector),通过实例选择器可以完成自定义负载均衡策略。

实例(instance)

Nacos 在 instance级别存在ephemeral字段,用于表示注册的实例是否是临时实例还是持久化实例:

  • 临时实例:不会在服务端持久化存储,需要通过上报心跳的方式进行保活,如果一段时间内没有上报心跳,则会被 Nacos 服务端踢除;再次加入后会重新将该实例注册。
  • 持久化实例:即使注册实例的客户端进程不在,这个实例也不会从服务端删除,只会将健康状态设为不健康。

自定义实例的构建

nacos支持服务设置元数据(例如:所属的应用或者所在的机房),客户端可以根据服务下挂载的实例元信息,来自定义负载均衡模式。

Nacos 也提供了另外的注册实例接口,使得用户在注册实例时可以指定实例的属性:

void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException;

实例的定义如下:

public class Instance {
    
    /**
     * 实例唯一ID
     */
    private String instanceId;
    
    /**
     * 对应IP
     */
    private String ip;
    
    /**
     * 端口
     */
    private int port;
    
    /**
     * 权重
     */
    private double weight = 1.0D;
    
    /**
     * 实例健康状态。标识该实例是否健康,一般心跳健康检查会自动更新该字段
     */
    private boolean healthy = true;
    
    /**
     * 是否启用
     */
    private boolean enabled = true;
    
    /**
     * 是否为临时实例
     *
     * @since 1.0.0
     */
    private boolean ephemeral = true;
    
    /**
     * 集群名称
     */
    private String clusterName;
    
    /**
     * 服务名称
     */
    private String serviceName;
    
    /**
     * 元数据
     */
    private Map<String, String> metadata = new HashMap<String, String>();
}

服务信息在由服务提供者上报之后,由服务消费者获取,从而完成信息的传递。


二、nacos服务发现配置

版本适配

相关框架的版本适配:

Spring Cloud Alibaba VersionSentinel VersionNacos VersionRocketMQ VersionDubbo VersionSeata Version
2021.0.1.0*1.8.31.4.24.9.22.7.151.4.2
2.2.7.RELEASE1.8.12.0.34.6.12.7.131.3.0
2.2.6.RELEASE1.8.11.4.24.4.02.7.81.3.0
2021.1 or 2.2.5.RELEASE or 2.1.4.RELEASE or 2.0.4.RELEASE1.8.01.4.14.4.02.7.81.3.0
2.2.3.RELEASE or 2.1.3.RELEASE or 2.0.3.RELEASE1.8.01.3.34.4.02.7.81.3.0
2.2.1.RELEASE or 2.1.2.RELEASE or 2.0.2.RELEASE1.7.11.2.14.4.02.7.61.2.0
2.2.0.RELEASE1.7.11.1.44.4.02.7.4.11.0.0
2.1.1.RELEASE or 2.0.1.RELEASE or 1.5.1.RELEASE1.7.01.1.44.4.02.7.30.9.0
2.1.0.RELEASE or 2.0.0.RELEASE or 1.5.0.RELEASE1.6.31.1.14.4.02.7.30.7.1
Spring Cloud Alibaba VersionSpring Cloud VersionSpring Boot Version
2021.0.1.0Spring Cloud 2021.0.12.6.3
2.2.7.RELEASESpring Cloud Hoxton.SR122.3.12.RELEASE
2021.1Spring Cloud 2020.0.12.4.2
2.2.6.RELEASESpring Cloud Hoxton.SR92.3.2.RELEASE
2.1.4.RELEASESpring Cloud Greenwich.SR62.1.13.RELEASE
2.2.1.RELEASESpring Cloud Hoxton.SR32.2.5.RELEASE
2.2.0.RELEASESpring Cloud Hoxton.RELEASE2.2.X.RELEASE
2.1.2.RELEASESpring Cloud Greenwich2.1.X.RELEASE
2.0.4.RELEASE(停止维护,建议升级)Spring Cloud Finchley2.0.X.RELEASE
1.5.1.RELEASE(停止维护,建议升级)Spring Cloud Edgware1.5.X.RELEASE

配置

dependencyManagement元素

dependencyManagement元素提供了一种管理依赖版本号的方式。在dependencyManagement元素中声明所依赖的jar包的版本号等信息,那么所有子项目再次引入此依赖jar包时则无需显式的列出版本号。

dependencyManagement中定义的只是依赖的声明,并不实现引入,因此子项目需要显式的声明需要用的依赖。

为子项目指定依赖版本:

<dependencyManagement>
    <dependencies>
        <!-- SpringCloud 微服务 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- SpringBoot 依赖配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>


        <!-- SpringCloud Alibaba 微服务 -->
        <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>

        <!-- Alibaba Nacos 配置 -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>${alibaba.nacos.version}</version>
        </dependency>


        <!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--        yml提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 解决版本不再默认优先加载bootstrap.yml文件 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>ObsApplication</mainClass>
                <excludeDevtools>true</excludeDevtools>
                <includeSystemScope>true</includeSystemScope>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

子项目的配置:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

yml的配置:

# Tomcat
server:
  port: 6002
spring:
  application:
    name: simtek-fmu
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: ${NACOS_ADDR:127.0.0.1:6100}
        group: cosimcloud
        namespace: public

maven依赖中的<scope>provided</scope>

  • compile:默认的scope,表示 dependency 都可以在生命周期中使用;而且会传递到依赖的项目中
  • provided:表明了dependency 由JDK或者容器提供,只能作用在编译和测试时,同时没有传递性
  • system:跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它
  • runtime:表示dependency不作用在编译时,但会作用在运行和测试
  • test:表示dependency作用在测试时,不作用在运行时

@EnableDiscoveryClient注解

@EnableDiscoveryClient能够让注册中心发现,扫描到该服务,不局限注册中心;而注解@EnableEurekaClient只适用于Eureka作为注册中心。

在启动类添加注解:

@SpringBootApplication
@EnableDiscoveryClient
public class CosimcloudFmuApplication {

    public static void main(String[] args) {
        SpringApplication.run(CosimcloudFmuApplication.class, args);
    }

}

三、nacos配置中心

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

引入依赖:

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

yml配置:

  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
  • shared-configs 表示共享配置
spring:
  cloud:
    nacos:
      config:
        # 配置中心地址
        server-addr: ${NACOS_ADDR:127.0.0.1:6100}
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - ${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

四、参考资料

小白也能懂的 Nacos 服务模型介绍