微服务架构 | 2.2 Alibaba Nacos 的统一配置管理

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Nacos 致力于解决微服务中的统一配置、服务注册与发现等问题。它提供了一组简单易用的特性集,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理;

前言

参考资料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
《Nacos 官网》

Nacos 致力于解决微服务中的统一配置、服务注册与发现等问题。它提供了一组简单易用的特性集,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理;


1. Nacos 配置中心基础知识

1.1 Nacos 在配置中心中的功能

  • CRUD、版本管理、灰度管理、监听管理、推送轨迹、聚合数据等功能;

1.2 Nacos 配置管理 Data ID 的构成

  • ${prefix}-${spring.profiles.active}.${file-extension}
  • 默认为:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

    • prefix:默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置;
    • spring.profiles.active:即为当前环境对应的 profile。当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
    • file-exetension:为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型;

Nacos 配置管理 dataId 的构成

1.3 Nacos 配置的回滚机制

  • Nacos 会记录配置文件的历史版本默认保留 30 天,此外还有一键回滚功能,回滚操作将会触发配置更新;

Nacos 配置的回滚

1.4 Nacos 配置的图形化管理界面

  • 配置管理;

配置列表

  • 命名空间;

命名空间

1.5 Namespace、Group、Data ID 三者的关系

Namespace、Group、Data ID 三者的关系

  • 类似 Java 里面的 package 名和类名,最外层的 Namespace 是可以用于区分部署环境的,GroupData ID 逻辑上区分两个目标对象;
  • 默认情况下,Namespace=publicGroup=DEFAULT_GROUPCluster=DEFAULT

    • Namespace 命名空间:主要用来实现隔离,用于解决多环境及多租户数据的隔离问题。比如有三个环境:开发、测试、生产环境,可以创建三个Namespace,不同的Namespace 之间是隔离的;
    • Group 分组:可以把不同的微服务划分到同一个分组里面去,用来实现 Data ID 分组管理的机制;
    • Data ID:通常用于组织划分系统的配置集;
    • Cluster 簇:对指定微服务的一个虚拟划分;
    • Instance 实例:微服务的实例;
  • 官方的建议是,通过 Namespace 来区分不同的环境,而 Group 可以专注在业务层面的数据分组;

1.6 Nacos 对配置的 CRUD

  • 主要通过提供 Open API 接口或 SDK 实现;
  • 客户端通过 Open API 或调用 SDK 接口发送请求给服务器,服务器解析请求,并做相应的处理;

配置的 CRUD

对配置的操作 SDK Open API 说明
发布配置 public boolean publishConfig(String dataId, String group, String content) throws NacosException POST: /nacos/v1/cs/configs 将配置保存到 Nacos Config Server 中
删除配置 public boolean removeConfig(String dataId, String group)throws NacosException DELETE: /nacos/v1/cs/configs 删除配置中心的指定配置
获取配置 public string getConfig(String dataId, String group, long timeoutMs) throws NacosException GET: /nacos/v1/cs/configs 从 Nacos Config Server 中读取配置
监听配置 public void addListener(String dataId, String group, Listener listener) POST: /nacos/v1/cs/configs/listener 订阅感兴趣的配置,当配置发生变化时可以收到一个事件

1.7 Nacos 动态监听的长轮询机制

  • 一般来说,动态监听有两种机制:
比较项 Pull 机制 Push 机制
说明 客户端从服务端主动拉取数据 服务端主动把数据推送到客户端
缺点 不能保证数据实时性;在服务端配置长时间不更新的情况下,客户端的定时任务会做一些无效的 Pull 如果客户端的数量比较多,服务端需要耗费大量的内存资源来保存每个连接;需要心跳机制来维持每个连接状态
  • Nacos 的解决方案:长轮询机制

Nacos 动态监听的长轮询机制

  • 如果客户端发起 Pull 请求,服务端收到请求之后,先检查配置是否发生了变更:

    • 变更:返回变更配置;
    • 无变更:设置一个定时任务,延期 29.5s 执行,把当前的客户端长轮询连接加入 allSubs 队列;
  • 在这 29.5s 内的配置变化:

    • 配置无变化:等待 29.5s 后触发自动检查机制,返回配置;
    • 配置变化:在 29.5s 内任意一个时刻配置变化,会触发一个事件机制,监听到该事件的任务会遍历 allSubs 队列,找到发生变更的配置项对应的 ClientLongPolling 任务,将变更的数据通过该任务中的连接进行返回。相当于完成了一次 PUSH 操作;
  • 长轮询机制结合了 Pull 机制和 Push 机制的优点;
  • 源码分析详情请见:微服务架构 | *2.5 Nacos 长轮询定时机制的源码分析

1.8 Nacos 配置中心的源码分析


2. Nacos 基础配置

以 Data ID 方案为例,更多方案详情请见本篇第三点《3. Nacos 加载配置的三种方案》;

2.1 下载 Nacos 服务器

2.2 引入 pom.xml 依赖文件

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

2.3 修改 yml 配置文件

  • bootstrap.yml
# nacos配置
server:
  port: 18082

spring:
  application:
    name: nacos-config-client     #必须,构成 Nacos 配置管理 Data ID 字段的一部分
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848     #Nacos 服务注册中心地址
      config:
        server-addr: localhost:8848     #Nacos 作为配置中心地址
        file-extension: yaml     #指定 yaml 格式的配置
        
        # prefix: hhh     #Data ID 的前缀,如果不指定,就是 nacos-config-client-dev.yaml。指定后,是 hhh-dev.yaml
        # refresh: true      #是否动态刷新
        
        # group: DEFAULT_GROUP     #指定组
        # namespace: PUBLIC     #指定命名空间 ID
  • application.yml
spring:
  profiles:
    active: dev # 表示开发环境

2.4 在主程序类上添加注解

  • @EnableDiscoveryClient:使用其他组件(Nacos、zookeeper、Consul)作为注册中心;

2.5 编写业务类

  • 这里仅编写一个 controller 作为示例:
@RestController
@RefreshScope //使当前类下的配置支持 Nacos 的动态刷新功能
public class ConfigClientController{
    @Value("${config.info}")
    private String configInfo;

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

2.6 在 Nacos 服务器中添加配置信息

  • 在 Nacos 服务器里新建并添加配置:

Nacos 新建配置
Nacos 新建配置2
Nacos 新建配置成功

  • 启动服务,调用接口:http://localhost:18082/config/info 获取配置信息;

启动服务,调用接口

2.7 报错无法装配 bean

  • 注意:如果 .yml 和 Nacos 服务器配置的 Data ID 匹配不上,将导致 ConfigClientController 类里的 ${config.info} 找不到,最终报 ConfigClientController 无法装配的错误,如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.configClientController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'config.info' in value "${config.info}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:380) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:356) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:389) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:186) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.cloud.context.scope.refresh.RefreshScope.eagerlyInitialize(RefreshScope.java:134) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.cloud.context.scope.refresh.RefreshScope.start(RefreshScope.java:125) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.cloud.context.scope.refresh.RefreshScope.onApplicationEvent(RefreshScope.java:119) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.cloud.context.scope.refresh.RefreshScope.onApplicationEvent(RefreshScope.java:73) ~[spring-cloud-context-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    ......


3. Nacos 加载配置的三种方案

  • 以下对 bootstrap.yml 的修改都可以在启动时配置 JVM 环境替代,使用如下命令:
  • -Dspring.profiles.active=${profile}

3.1 Data ID 方案

  • 新建三个 Data ID 的环境:

三个 Data ID 的环境

  • 指定 spring.profile.active 中的配置,重启服务,可以看到配置已经切换成其他环境了:
spring:
  profiles:
    active: prod

配置切换成其他环境

3.2 Group 方案

  • 新建三个 Group 的环境:

三个 Group 的环境

  • 指定 spring.profile.activespring.cloud.nacos.config.group 中的配置,重启服务,可以看到配置已经切换成其他环境了:
  • application.yml
spring:
  profiles:
    active: info #修改
  • bootstrap.yml
server:
  port: 18082
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 
      config:
        server-addr: localhost:8848
        file-extension: yaml
        group: PROD_GROUP #新增

配置切换成其他 Group 环境

3.3 Namespace 方案

  • 新建两个 Namespace 的环境:

新建两个命名空间
三个命名空间

  • 克隆 / 新建几份配置文件到新的命名空间,然后编辑修改;

克隆三份配置文件到其他命名空间

  • 指定 spring.profile.activespring.cloud.nacos.config.group 中的配置,重启服务,可以看到配置已经切换成其他环境了:
  • application.yml
spring:
  profiles:
    active: dev #修改
  • bootstrap.yml
server:
  port: 18082
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 
      config:
        server-addr: localhost:8848
        file-extension: yaml
        group: DEFAULT_GROUP #新增
        namespace: 48b2da7d-0b26-4c15-907b-9a379db8f7de #新增,命名空间的 ID,在新建命名空间时会给出

配置切换成其他命名空间环境


相关文章
|
12天前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
25 4
|
12天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
31 3
|
12天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
26 3
|
1月前
|
JSON SpringCloudAlibaba Java
Springcloud Alibaba + jdk17+nacos 项目实践
本文基于 `Springcloud Alibaba + JDK17 + Nacos2.x` 介绍了一个微服务项目的搭建过程,包括项目依赖、配置文件、开发实践中的新特性(如文本块、NPE增强、模式匹配)以及常见的问题和解决方案。通过本文,读者可以了解如何高效地搭建和开发微服务项目,并解决一些常见的开发难题。项目代码已上传至 Gitee,欢迎交流学习。
128 1
Springcloud Alibaba + jdk17+nacos 项目实践
|
30天前
|
Java Nacos 微服务
微服务中间件之Nacos
Nacos是阿里巴巴开源的动态服务发现、配置管理和服务管理平台,支持服务注册与发现、配置管理及服务健康监测。采用Spring Cloud、Spring Boot、Raft算法等技术,适用于微服务架构和云原生应用,提供简单易用的安装部署方式和丰富的应用场景。
145 2
|
21天前
|
数据管理 Nacos 开发者
"Nacos架构深度解析:一篇文章带你掌握业务层四大核心功能,服务注册、配置管理、元数据与健康检查一网打尽!"
【10月更文挑战第23天】Nacos 是一个用于服务注册发现和配置管理的平台,支持动态服务发现、配置管理、元数据管理和健康检查。其业务层包括服务注册与发现、配置管理、元数据管理和健康检查四大核心功能。通过示例代码展示了如何在业务层中使用Nacos,帮助开发者构建高可用、动态扩展的微服务生态系统。
64 0
|
1月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
61 0
|
7天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
5天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
5天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
16 1
服务架构的演进:从单体到微服务的探索之旅