Nacos的基本使用(注册中心、配置中心)

1、Nacos的基本介绍

Nacos 官方介绍:Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您实现动态服务发现、服务配置管理、服务及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构的服务基础设施。

Nacos 是阿里巴巴的开源的产品,现在是 SpringCloud 中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。Nacos是用来发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos的一大优势是整合了注册中心、配置中心功能。

Nacos主要提供以下四大功能:

  1. 服务发现与服务健康检查。Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
  2. 动态配置管理。动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。
  3. 动态DNS服务。Nacos提供基于DNS协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让三方应用方便地查阅及发现。
  4. 服务和元数据管理。Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。

这里动态配置管理的特性说明了Naocs的配置管理能力。

 

2、Nacos的下载安装

2.1、Nacos的下载安装(window版)

2.1.1、下载 nacos 安装包

可直接到 nacos 的 github 网站的 release 中下载,下载链接:https://github.com/alibaba/nacos/releases

如上图,.zip 包是用于 window 系统的,.tar.gz 包是用于 Linux 系统的。

 

2.1.2、安装 nacos

下面我们安装一个 window 系统版本的,安装 nacos 其实非常简单,只需将压缩包解压即可。

解压后目录结构如下:

目录说明:

  • bin:启动脚本
  • conf:配置文件

Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。如果无法关闭占用8848端口的进程,也可以进入安装目录的 conf/application.properties 文件,修改配置文件中的端口:

 

 

2.1.3、启动nacos

启动 nacos 非常简单,进入安装目录的 bin 目录下,直接双击 startup.cmd 文件,但是这样默认是以集群模式启动的 nacos,此时就会读取集群的一些配置文件,可能会导致一些报错,所以我们可以通过 cmd 命令行来指定运行时的一些配置,比如下面命令指定以单体模式运行 nacos:

startup.cmd -m standalone

启动结果如下:

在浏览器输入地址:http://127.0.0.1:8848/nacos 即可访问到 nacos,如下:

默认的登录账户和密码都是 nacos。

 

2.2、Nacos的下载安装(Linux版)

Linux 或者 Mac 安装方式都跟 Windows 差不多,都只是解压压缩包,执行命令文件即可。

Nacos 依赖于JDK运行,所以 Linux上 也需要安装 JDK 才行。

 

3、Nacos注册服务

nacos 搭建 nacos client 并注册服务跟 eureka 的流程差不多,先引入客户端依赖,然后添加配置即可。启动 nacos client 后就会自动往注册中心注册服务。需注意,nacos 服务端需保持启动状态,否则连接不上服务端将会注册失败。

首先,我们先引入依赖,下面假设父工程 springclouddemo 作为依赖管理,父工程下面有子模块 order-service 作为服务需注册到 nacos 注册中心当中。

在父工程 springclouddemo 的 pom.xml 中添加 nacos 管理依赖:

<!--nacos的管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

在子模块 order-service 中添加客户端依赖:

<!-- nacos客户端依赖包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

往子模块 order-service 的配置文件 application.yaml 中添加配置,如下:

server:
  port: 8081

spring:
  application:
    name: orderservice #设置当前应用名称,在eureka中Aoolication显示,通过该名称可以获取路径
  cloud:
    nacos:
      server-addr: http://localhost:8848 # nacos服务地址

启动order-service 的入口启动类即可,可以在 nacos 页面中的服务列表中看到 order-service 已经注册成功。如下:

使用 nacos 和使用 eureka 来调用另一服务的接口的代码是一样的,也就是可以跟使用 eureka 时一样,使用 RestTemplate 来发起 http 请求,并且使用服务名来替代目标服务的 ip 和端口,避免 ip 和端口需要硬编码写死的情况。

 

详细的 pom.xml 文件内容示例:

父工程 springclouddemo 的 pom.xml 文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springclouddemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springclouddemo</name>
    <description>Demo project for Spring Boot</description>

    <modules>
        <module>eureka-server</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>

    <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

order-service 子模块的 pom.xml 文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>springclouddemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>order-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order-service</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- nacos客户端依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

4、Nacos服务分级存储模型(服务、集群、实例)

Nacos服务分级存储模型:一级是服务;二级是集群,比如可以按区域机房划分集群,北京集群、上海集群、广州集群等等;三级是实例,例如北京机房的某台服务器部署的某服务

在服务互相调用时我们应该尽可能地去选择本地集群,即同一集群的服务,因为跨集群调用延迟较高,只有当本地集群的需调用的服务不可访问时,再去访问其它集群。

 

4.1、给nacos服务配置集群

在 nacos 注册的服务如果没有配置集群的话,默认是没有集群的,也就是在一个名为 DEFAULT 的集群下,如下:

我们可以在 nacos 服务的配置文件中通过配置指定该服务的集群,只需在配置文件比如 application.yml 中添加 spring.cloud.nacos.discovery.cluster-name 属性即可,如下:

spring:
  application:
    name: orderservice
  cloud:
    nacos:
      server-addr: http://localhost:8848 # nacos服务地址
      discovery:
        cluster-name: HZ # 配置集群名称,例如:HZ,代指杭州集群

此时,注册在 nacos 中的服务可以看到它的集群名称就是我们配置的集群名称,如下:

 

4.2、配置优先访问同一集群

在服务互相调用时我们应该尽可能地去选择本地集群,即同一集群的服务,因为跨集群调用延迟较高,只有当本地集群的需调用的服务不可访问时,再去访问其它集群。但是使用 springcloud 在 nacos 中注册的服务,默认的负载均衡策略是轮询,也就是会轮询各个服务,不会区别是否同一集群。我们可以通过配置负载均衡策略来使得调用服务时优先选择同一集群的服务。

假设 order-service 和 user-service 两种服务在各个集群中都有实例存在,而我们想要配置在 order-service 中调用 user-service 服务的接口时,优先选择同一集群的服务,只需在 order-service 服务中设置负载均衡的 IRule 为 NacosRule ,如下:

userservice:    #指定给某个目标服务发起请求时的负载均衡规则,这里是目标服务的服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  #负载均衡规则

NacosRule 负载均衡策略会优先寻找与自己在同一集群的服务,只有在同一集群中找不到服务提供者,才去其它集群寻找,并且当使用了其他集群的服务时,服务消费者中会提示类似以下的警告信息:

如果一个集群中的服务提供者有多个实例,则会使用随机调用的策略。

 

4.3、配置实例的权重

当配置了优先访问同一集群内的服务时,在同一集群内如果有多个服务提供者实例的话,此时会使用随机访问的策略。当有时候,服务器设备之间的性能是有差异,部分实例所在的机器性能较好,另一些较差,我们可能会希望性能好的机器能承担更多的用户请求,而 Nacos 也提供了权重配置来让我们控制实例的访问频率,权重越大则访问频率越高。

我们可以在 Nacos 的控制台中设置实例的权重值,如下:

点击实例后面的编辑按钮,弹出窗口可以设置权重值,如下:

所有的实例的权重值默认都是1,我们可以将将权重值设置为 0~1,权重越低,被访问到的概率就越低,为 0 时则完全不会被访问到。

 

5、nacos环境隔离(namespace命名空间)

Nacos 中服务存储和数据存储的最外层都是一个名为 namespace 的东西,用来做最外层隔离,namespace 是用来来实现环境隔离功能的。

nacos 的领域模型划分:

 

  • Nacos 中可以有多个 namespace,默认为“public",每个namespace都有唯一id
  • 不同 namespace 之间相互隔离,不同 namespace 之间的服务互相不可见
  • namespace 下可以有分组 group、服务 service 等。group 用作微服务的分组,不同的分组之间微服务也不能互相不可见。服务的默认分组都是 “DEFAULT_GROUP”,分组一般来说不用修改。

同一个namespace,同一个group下,不同的集群 cluster-name 之间的服务是可以相互调用的。但是应该尽量避免服务的跨集群调用,因为不同集群通常是跨地域部署的,跨地域会有网络延时,所以要优先保证同一集群调用。

 

5.1、新增namespace

默认情况下,所有 service、data、group 都在同一个 namespace,名为 public(保留空间),如下:

  

我们可以命名空间菜单页新增 namespace,如下:

  

新增结果如下:

 

5.2、配置服务的namespace

给微服务配置 namespace 可以通过修改服务的配置文件来实现,只需修改 spring.cloud.nacos.discover.namespace 属性即可。

例如,修改 order-service 的 application.yml 文件:

spring:
  application:
    name: orderservice #设置当前应用名称,在eureka中Aoolication显示,通过该名称可以获取路径
  cloud:
    nacos:
      server-addr: http://localhost:8848 # nacos服务地址
      discovery:
        cluster-name: HZ # 配置集群名称,例如:HZ,代指杭州集群
        namespace: 202e0704-a251-41f3-9d67-8e640688c5a5 #这里填的是命名空间的id而不是名称

结果如下:

 

6、nacos注册中心运行机制

运行机制如下图:

nacos 运行机制跟 eureka 差不多,都支持服务注册和服务拉取,都支持服务提供者心跳方式做健康检测。但是 nacos 不仅仅可以由服务区拉取服务列表,也可以由注册中心主动推送服务变更信息给服务,这样服务得到的服务清单能得到及时更新。并且 nacos 中的服务还区分临时实例和非临时实例。

临时实例和非临时实例的区别:

  • 临时实例:nacos 采用心跳模式来检测临时实例的状态,也就是需要由服务实例来主动发出心跳。临时实例如果心跳不正常则会被直接剔除
  • 非临时实例:nacos 采用主动检测模式来检测非临时实例的状态,也就是由注册中心主动去询问实例的状态。非临时实例状态异常并不会被剔除。

默认情况下,在 nacos 中注册的服务实例都是临时实例。要想修改为非临时实例,可以通过修改服务的配置文件来实现,只需修改 spring.cloud.nacos.discover.ephemeral 属性即可,如下:

 

6.1、Nacos与Eureka的区别

Nacos与Eureka的区别如下:

  1. Nacos 支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  2. 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  3. Nacos 支持服务列表变更的消息推送模式,服务列表更新更及时
  4. Nacos 集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

 

posted @ 2022-04-22 17:00  wenxuehai  阅读(13842)  评论(0编辑  收藏  举报
//右下角添加目录