深入理解Spring Cloud一(3)Nacos配置中心

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Spring Cloud一(3)Nacos配置中心相关的知识,希望对你有一定的参考价值。

参考技术A 通过上一节的介绍,我们已经知道了配置加载的扩展点。下面我们已具体的Nacos配置中心来进行说明。

NacosConfigBootstrapConfiguration是@BootstrapConfiguration的配置类,在bootstrap 的SpringApplication创建的过程中,会加载这个类。这个Configuration类包括两个Bean,分别是NacosConfigManager,NacosPropertySourceLocator。

NacosConfigManager的核心作用是创建NacosConfigService,通过NacosConfigService从远程配置中心拉取配置。

NacosPropertySourceLocator是PropertySourceLocator的实现类,上一节已经详细介绍过PropertySourceLocator。

NacosConfigAutoConfiguration是@EnableAutoConfiguration的配置类,当application创建SpringApplication的过程中会被加载,会加载两个重要的Bean,NacosContextRefresher和NacosConfigManager,NacosConfigManager上面已经结束过。

NacosContextRefresher主要作用就是注册Nacos监听器。

监听器又是如何触发的?

Nacos使用长轮询方式获取配置,判断文件是否有变动,如果有变动则触发监听器。

NacosConfigService创建的时候,会创建ClientWorker对象,同时会创建长轮询任务。

我们继续往下看LongPollingRunnable

如果文件MD5不一致,则触发监听器

最终实现回调

判断文件是否变动的核心是长轮询,客户端比较简单,只需要设置较长时间的读超时即可。后面我们会继续探究Nacos服务端的长轮询是如何时间的。

Spring Cloud Alibaba Nacos服务注册和配置中心

Spring Cloud Alibaba Nacos服务注册和配置中心

由于 Spring Cloud Netflix 项目进入维护模式(将模块置于维护模式意味着 Spring Cloud 团队将不会再向模块中添加新功能,只会修复 block 级别的 bug 以及安全问题),阿里巴巴团队为我们提供了一套新的微服务开发一站式解决方案

详见官方介绍:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

一、Nacos 概述

什么是Nacos?

  • Nacos(Dynamic Naming and Configuration Service):一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心。我们可以理解为:Nacos = 服务注册中心 + 配置中心;等价于 Nacos = Eureka + Spring Cloud Config + Spring Cloud Bus

  • Nacos 可以替代 Eureka 来实现 服务注册中心、可以替代 Spring Cloud Config 来实现服务配置中心、可以替代 Spring Cloud Bus 来实现 配置的全局广播。Nacos 是更强调云原生时代支持 “服务治理、服务沉淀、共享、持续发展” 理念的注册中心和配置中心。(附:Nacos 官网)

各注册中心比较:

Nacos的安装运行:

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

  • 下载解压后,打开 bin 目录,打双击 startup.cmd 均可启动

  • 浏览器地址栏输入 localhost:8848/nacos 登录,默认用户名密码都是 nacos,主页面如下:

二、Nacos作为注册中心

项目结构:

2.1 基于Nacos的服务提供者

1、建moudle作为服务端cloudalibaba-provider-payment9001

2、引入依赖

  • 父pom引入spring-cloud-alibaba 依赖

    <!--spring cloud alibaba 2.1.0.RELEASE-->
    <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>
    
  • 当前模块pom引入 nacos-discovery 依赖

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

3、applicaiton.yml 文件配置

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址
# 做监控需要把这个全部暴露出来
management:
  endpoints:
    web:
      exposure:
        include: '*'

4、主启动类,需要使用@EnableDiscoveryClient注解

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

5、业务类

@RestController
public class PaymentController 

    @Value("$server.port")
    private String serverPort;

    @GetMapping(value = "/payment/nacos/id")
    public String getPayment(@PathVariable("id") Integer id) 
        return "nacos registry, serverPort: "+ serverPort+"\\t id"+id;
    


6、测试

  • 这里不像eureka还要写注册中心微服务,直接安装打开nacos即可。

  • 启动服务模块,进入 Nacos 控制台,在 服务管理 → 服务列表 中可以看到,我们定义的服务名 nacos-payment-provider 已经成功注册到 Nacos 注册中心。

  • 访问http://localhost:9001/payment/nacos/1

7、相同配置再新建一个module 9002

再来个 cloudalibaba-provider-payment9002模块作为服务端,将其与 9001 形成集群,以集群的方式对外提供服务,并将其也注册到 Nacos 中。

2.2 基于Nacos的服务消费者

Nacos 默认支持负载均衡:

  • 使用 Eureka 时,服务调用使用的是 基于Ribbon 的 RestTemplate + @LoadBalanceFeign 的方式进行。Feign 整合 Ribbon 默认支持负载均衡我们的 Nacos 也整合了 Ribbon 默认支持负载均衡。

1、新建module作为服务消费者cloudalibaba-consumer-nacos-order83

2、引入nacos-discovery依赖

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

3、applicaiton.yml 文件配置

server:
  port: 83

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

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

4、主启动类,需要使用@EnableDiscoveryClient注解

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

5、业务类

@Configuration
public class ApplicationContextBean 

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() 
        return new RestTemplate();
    


@RestController
public class OrderNacosController 

    @Resource
    private RestTemplate restTemplate;

    @Value("$service-url.nacos-user-service")
    private String serverURL;

    @GetMapping("/consumer/payment/nacos/id")
    public String paymentInfo(@PathVariable("id") Long id) 
        return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
    


6、测试

  • 启动9001、9002、83

  • 测试链接:http://localhost:83/consumer/payment/nacos/1,发现9001与9002交替出现,即轮询负载均衡

2.3 Nacos与其他注册中心对比

Nacos可以在CP与AP之间切换:

  • C 一致性 A 高可用 P 容错性。参考:CAP原则,主流选用的都是 AP 模式,保证系统的高可用。

何时选择使用何种模式?

  • AP:

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

  • CP:

    如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

Nacos 集群默认支持的是CAP原则中的 AP原则,但是 也可切换为CP原则切换命令如下:

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

三、Nacos作为配置中心

Nacos 可以替代 Config + Bus 来用作 服务配置中心。附:Nacos服务配置中心官方文档。Nacos 用作服务配置中心,分为 基础配置(简单使用)分类配置(多环境使用 dev、test、prod等环境)。接下来就介绍 Nacos 用作服务配置中心。

3.1 Nacos基础配置

1、新建模块 cloudalibaba-config-nacos-client3377 用作配置中心,并将其注册到 Nacos 中

2、pom 引入 nacos-config 依赖

<!--引入nacos-config配置-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--注册到 Nacos,需引入nacos-discovery配置-->
<!--引入nacos-discovery配置-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3、进行yml配置

此处需要配置 bootstrap.ymlapplication.yml 两个文件。

原因:Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于applicationbootstrap.yml 用作系统级资源配置项,application.yml 用作用户级的资源配置项。在项目中两者配合共同生效,bootstrap.yml 优先级更高

  • bootstrap.yml

    # nacos配置
    server:
      port: 3377
    
    spring:
      application:
        name: nacos-config-client
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 #Nacos服务注册中心地址
          config:
            server-addr: localhost:8848 #Nacos作为配置中心地址
            file-extension: yaml #指定yaml格式的配置
    
    # $spring.application.name-$spring.profile.active.$spring.cloud.nacos.config.file-extension
    # nacos-config-client-dev.yaml
    
  • application.yml

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

4、主启动类,添加@EnableDiscoveryClient注解

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

5、业务类添加 @RefreshScope 实现配置自动更新

@RestController
@RefreshScope //在控制器类加入@RefreshScope注解使当前类下的配置支持Nacos的动态刷新功能。
public class ConfigClientController 
    @Value("$config.info")
    private String configInfo;

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

6、Nacos中添加配置项

进入 Nacos → 配置管理 → 配置列表 → + 号 添加配置项。Data ID 按规则编写。

Data ID 命名规则:

官网:https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

dataId 的完整格式如下:

$prefix-$spring.profile.active.$file-extension
  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profile.active 即为当前环境对应的 profile。注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 $prefix.$file-extension(建议:不要让 spring.profile.active 为空,或许会有一些意外的问题)
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

七、测试

通过 http://localhost:3377/config/info 测试,发现可以正确获取 Nacos 配置中心的配置信息。

自带动态刷新:修改nacos中的yaml配置文件,再次调用查看配置,发现配置刷新了

3.2 Nacos分类配置

项目开发中,一定会遇到 多环境多项目管理 问题。遇到下面问题时,Nacos 基础配置显然无法解决这些问题,接下来就对 Nacos 命名空间Group 相关概念的了解。

3.2.1 Nacos的命名规则说明

Nacos 命名由 Namespace(命名空间) + Group(分组) + Data ID(实例ID) 三部分组成。最外层 Namespace 用于区分部署环境;Group 和 Data ID 逻辑上用于区分两个目标对象。

默认情况下:Namespace = publicGroup = DEFAULT_GROUPCluster=DEFAULT

  • Namespace 主要用来实现隔离,Nacos 默认的命名空间是 public。比方说我们现在有三个环境:开发测试生产环境,我们就可以创建三个 Namespace,不同的 Namespace 之间是隔离的;

  • Group 是一组配置集,是组织配置的维度之一。默认是 DEFAULT_GROUP。通过一个有意义的 名称 对配置集进行分组,从而区分 Data ID 相同的配置集。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,就可以把不同的微服务划分到同一个分组里面去,从而解决问题2;如 database_url 配置和 MQ_topic 配置。

  • Service 微服务;一个 Service 可以包含多个 Cluster(集群),Nacos 默认 Cluster 是 DEFAULT,Cluster 是对指定微服务的一个虚拟划分。比方说为了容灾,将 Service 微服务分别部署在了杭州机房和广州机房,这是就可以给杭州机房的 Service 微服务起一个集群名称(HZ),给广州机房的 Service 微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。

  • Instance,就是一个个微服务实例。

3.2.2 DataID方案

  • 指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置

    这里命名空间是默认的public,Group也是默认的。

  • 通过spring.profile.active属性就能进行多环境下配置文件的读取

  • 重启3377 测试http://localhost:3377/config/info,成功读取到test配置下的config.info

3.2.3 Group方案

  • 默认Group是DEFAULT_GROUP,现在通过Group实现环境分区

1、新建一个配置文件,添加到DEV_GROUP分组

2、新建一个配置文件,添加到TEST_GROUP分组

3、在config下增加一条group的配置即可。可配置为DEV_GROUP或TEST_GROUP

4、测试:

3.2.4 namesapce方案

1、新建dev/test的Namesapce

  • 服务列表中可以看到不同的Namespace

2、在这两个新建的namespace中分别新建三个不同分组的配置文件

3、修改3377的yml文件

  • bootstrap:

  • application:

4、测试

  • dev namesapce:

  • test namesapce:

四、Nacos 集群搭建和持久化配置(待补)

参考博客:Nacos 集群搭建和持久化配置(Linux)

以上是关于深入理解Spring Cloud一(3)Nacos配置中心的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Alibaba Nacos服务注册和配置中心

Spring Cloud Alibaba Nacos服务注册和配置中心

Spring cloud&Alibaba面试题

springcloud 微服务Spring Cloud Alibaba 整合Nacos实战

springcloud 微服务Spring Cloud Alibaba Nacos使用详解

spring cloud集成nacos