vlambda博客
学习文章列表

使用Nacos实现服务注册与发现和统一配置中心管理

什么是Nacos?

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos关键特性包括:

  • 服务发现和服务健康监测

    Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

  • 动态配置服务

    动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

    动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

    配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

    同时提供了配置的版本跟踪,一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱既用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

  • 动态 DNS 服务

  • 服务及其元数据管理

使用 Nacos 简化服务发现、配置管理、服务治理及管理的解决方案,让微服务的发现、管理、共享、组合更加容易。

一、下载安装修改配置

  1. 修改nacos数据 持久化到数据库

  • 找到 %NACOS_HOME%/conf目录 下有 nacos-mysql.sql导入到数据库。

  • 修改application.properties文件 增加以下mysql连接配置:

    spring.datasource.platform=mysql

    db.num=1
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=root
    db.password=123456

cluster.conf.example 是用来配置nacos集群的文件,如需配置,则将修改名为cluster.conf

里面写上nacos各服务器的http://IP:端口号,默认nacos在linux中启动是以集群的方式启动,既不用加上 -m cluster参数,如是在windows下启动的nacos 默认是以单机的形式启动的 则需要加上 -m cluster参数。

startup.cmd -m cluster  //windows下启动集群方式(默认单机)

sh startup.sh //linux下启动集群的方式(默认集群)

sh startup.sh -m standalone //linux启动单机模式

nacos集群可以中间加一个nginx即可

二、服务注册与发现

通过实现一个简单的 echo service 演示如何在您的 Spring Cloud 项目中启用 Nacos 的服务发现功能,如下图示:

使用Nacos实现服务注册与发现和统一配置中心管理

1. 添加依赖

 <dependencies>
     <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>     
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <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>
    </dependencies>
</dependencyManagement>
  1. 配置服务提供者,从而服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。
  • server.port=8070
    spring.application.name=service-provider

    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  • 通过Spring Cloud原生注解@EnableDiscoveryClient开启服务主持发现功能:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosProviderApplication {

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

     @RestController
     class EchoController {
      @GetMapping("/echo/{string}")
      public String echo(@PathVariable String string) {
       return "Hello Nacos Discovery " + string;
      }
     }
    }
  1. 配置服务消费者,从而服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。
  • server.port=8080
    spring.application.name=service-consumer

    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  • 通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能。给 RestTemplate 实例添加 @LoadBalanced 注解,开启 @LoadBalanced 与 Ribbon 的集成:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosConsumerApplication {

        //负载均衡 默认轮询算法
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

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

        @RestController
        public class TestController {

            private final RestTemplate restTemplate;

            @Autowired
            public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

            @GetMapping("/echo/{str}")
            public String echo(@PathVariable String str) {
                return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
            }
        }
    }

    启动 ProviderApplicationConsumerApplication ,调用 http://localhost:8080/echo/2018,返回内容为 Hello Nacos Discovery 2018

三、配置统一管理

  1. nacos控制台创建配置文件

    使用Nacos实现服务注册与发现和统一配置中心管理

# alibaba-nacos-config-dev.yaml文件:
nacos: 
  info: group public | alibaba-nacos-config-dev.yaml info

# my-config-test-1.yaml文件:
nacos: 
  info: group public | my-config-test-1.yaml info
  version: group public | my-config-test-1.yaml version=1

# my-config-test-2.yaml文件:
nacos: 
  info: group public | my-config-test-2.yaml info
  version: group public | my-config-test-2.yaml version=2
  1. 添加依赖

    <dependencies>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>
        </dependencies>
    </dependencyManagement>
  2. server:
      port: 9088

    spring:
      application:
        name: alibaba-nacos-config
      cloud:
        nacos:
          discovery:
            #服务注册到nacos服务中
            server-addr: 127.0.0.1:8848
          config:
           #nacos地址
            server-addr: 127.0.0.1:8848
            #默认文件拓展名为properties
            file-extension: yaml
            # 加载其它配置文件
            ext-config:
               #配置文件相同的属性,则数组最后一个生效
              - dataId: my-config-test-2.yaml
               #更改了配置文件是否自动刷新
                refresh: true
                group: DEFAULT_GROUP
              - dataId: my-config-test-1.yaml
                refresh: true
                group: DEFAULT_GROUP
             #指定命名空间 对不同环境下的配置文件将其隔离开来   
    #        namespace: 91251605-bb75-4469-9c82-6905013ca69e
       #指定配置文件所属组,同上类似,将其同个命名空间下的文件进行分组
    #        group: DEV_GROUP
  3. application.yml文件配置为开发环境

    spring:
      profiles:
        active: dev
  4. 创建启动类

    @SpringBootApplication
    @EnableDiscoveryClient
    public class AlibabaNacosConfigApplication {
        public static void main(String[] args) {
            SpringApplication.run(AlibabaNacosConfigApplication.class,args);
        }
        
        @RestController
        //更改了配置之后 自动刷新
      @RefreshScope
        class ConfigController {
            @Value("${nacos.info}")
            private String info;

            @Value("${nacos.version}")
            private String version;

            @GetMapping("/config")
            public String config(){
                return "info("+info+")| version("+version+")";
            }
        }
    }

浏览器访问:http://127.0.0.1:9088/config ,不出意外会出现如下内容

  • nacos.info在三个配置文件中都出现,由于alibaba-nacos-config-dev.yaml的优先级是最高的,所以取的是alibaba-nacos-config-dev.yaml的内容

  • nacos.version分别在其中两个文件中出现了,按照优先级匹配规则,取数组最后一个,则是my-config-test-1.yaml的内容

配置文件匹配规则:

When configurations are loaded by Nacos Config, basic configurations with DataId of ${spring.application.name}. ${file-extension:properties} , and DataId of ${spring.application.name}-${profile}. ${file-extension:properties} are also loaded. If you need to use different configurations from different environments, you can use the ${spring.profiles.active} configuration provided by Spring.

可以简单的理解为,加载的DataId为${spring.application.name}.${file-extension:properties}如果有配置${spring.profiles.active}则DataId为${spring.application.name}-${profile}.${file-extension:properties}

Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力 从 Nacos 拉取相关的配置。

  • A: 通过 spring.cloud.nacos.config.shared-dataids 支持多个共享 Data Id 的配置
  • B: 通过 spring.cloud.nacos.config.ext-config[n].data-id 的方式支持多个扩展 Data Id 的配置( 如果dataId中有相同的配置文件信息,则数组最后一个生效)
  • C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置

当三种方式共同使用时,他们的一个优先级关系是:A < B < C