《Spring Cloud Alibaba 从入门到实战》分布式配置

分布式配置

1、简介

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。

Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。

2、学习目标

  • 使用 Nacos Config 作为 Spring Cloud 分布式配置
  • 使用 Nacos Config 实现 Bean 动态刷新
  • 了解 Nacos Config 高级配置

3、详细内容

  • 快速上手:使用 Nacos Config 作为外部化配置源
  • 多文件扩展名支持:以 YAML 文件扩展名为例,讨论 Nacos Config 多文件扩展名支持
  • 动态配置更新:演示 @RefreshScope 特性,实现 Bean 动态刷新
  • 自定义扩展:自定义 namespace、Group 以及 Data Id 的配置扩展
  • 运维特性:演示 Nacos Config 高级外部化配置以及 Endpoint 内部细节

4、快速上手

引入 Nacos Config 的两种方式

Nacos Config 引入的方式同样也有两种,即 Aliyun Java Initializr(云原生应用脚手架)引入和 Maven pom.xml 依赖。

官方推荐使用 Aliyun Java Initializr 方式引入 Nacos Discovery,以便简化组件之间的依赖关系。

快速上手

以脚手架引入为例

选择三个组件:
在这里插入图片描述

生成的相应依赖

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

版本号问题

不过该 starter 并未指定版本,具体的版本声明在 com.alibaba.cloud:springcloud-alibaba-dependencies 部分

    <dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><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></dependencies></dependencyManagement>

它们的版本定义在 <properties> 元素中,即 2.2.1.RELEASE2.3.0.RELEASE

<properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.3.0.RELEASE</spring-boot.version><spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>

启动 Nacos 服务器

阿里为开发者提供了一套免费的 Nacos Server :进入 http://139.196.203.133:8848/nacos/ 查看控制台(账号名/密码为 nacos-configuration/nacos-configuration)。

具体启动方式参考 Nacos 快速开始。

操作流程官方示例

  1. 选择 “配置管理/配置列表”

  2. 由于服务是公共免费的,为了做好隔离,所以分布式配置的功能,请选择在 sandbox -configuration 的命名空间下操作

  3. Data ID 由应用名(nacos-config-sample)+ 文件后缀名(.properties) 组成,配置内容:

    user.name=nacos-config-sampleuser.age=90
    

    应用名:对应 spring.application.name=xxx 中的 xxx 部分

  4. 回到应用 nacos-config-sample 工程,在 resources 目录下新建名为 “application.properties" 文件,并配置以下内容:

    spring.cloud.nacos.config.server-addr=139.196.203.133:8848
    spring.cloud.nacos.config.username=nacos-configuration
    spring.cloud.nacos.config.password=nacos-configuration
    spring.cloud.nacos.config.namespace=sandbox-configuration
    
  5. 读取 Nacos Config 实现

    	@SpringBootApplicationpublic class NacosConfigSampleApplication {@Value("${user.name}")private String userName;@Value("${user.age}")private int userAge;@PostConstructpublic void init() {System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);}public static void main(String[] args) {SpringApplication.run(NacosConfigSampleApplication.class, args);}}
    
  6. 启动 Nacos Config 应用

    运行 nacos-config-sample 引导类 NacosConfigSampleApplication,观察控制台结果(截取关键日志信息):

    [init] user name : nacos-config-sample , age : 9
    

5、使用 Nacos Config 实现 Bean 动态刷新

Nacos Config 支持标准 Spring Cloud @RefreshScope 特性,即应用订阅某个 Nacos 配置后,当配置内容变化时,Refresh Scope Beans 中的绑定配置的属性将有条件的更新

所谓的条件是指 Bean 必须:

  1. 必须条件:Bean 的声明类必须标注 @RefreshScope
  2. 二选一条件:
    • 属性(非 static 字段)标注 @Value
    • @ConfigurationProperties Bean

除此之外,Nacos Config 也引入了 Nacos Client 底层数据变化监听接口, 即 com.alibaba.nacos.api.config.listener.Listener

Nacos Client:Nacos 客户端 API,也是 Nacos Config 底层依赖

@Value 场景分析

代码实现

@SpringBootApplication
@RestController
@RefreshScopepublic
class NacosConfigSampleApplication {@Value("${user.name}")private String userName;@Value("${user.age}")private int userAge;@PostConstructpublic void init() {System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);}@PreDestroypublic void destroy() {System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);}
}

当 Nacos Config 接收到服务端配置变更时,对应的 @RefreshScope Bean 生命周期回调方法会被调用,并且是【先销毁】,然后又【重新初始化】。

要意识到 NacosConfig 配置变更对 @RefreshScope Bean 生命周期回调方法的影响,避免出现重复初始化等操作。

注: Nacos Config 配置变更调用了 Spring Cloud API ContextRefresher,该 API 会执行以上行为。同理,执行 Spring Cloud Acutator Endpoint refresh 也会使用 ContextRefresher

@ConfigurationProperties Bean 的场景分析

1、新增 User 类

@RefreshScope
@ConfigurationProperties(prefix = "user")
public class User implements InitializingBean, DisposableBean {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}

2、修改 NacosConfigSampleApplication 代码

@SpringBootApplication
@RestController
@RefreshScope
@EnableConfigurationProperties(User.class)
public class NacosConfigSampleApplication {@Value("${user.name}")private String userName;@Value("${user.age}")private int userAge;@Autowiredprivate User user;@PostConstructpublic void init() {System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);}@PreDestroypublic void destroy() {System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);}@RequestMapping("/user")public String user() {return "[HTTP] " + user;}public static void main(String[] args) {SpringApplication.run(NacosConfigSampleApplication.class, args);}
}

主要改点:

  • 激活 @ConfigurationProperties Bean @EnableConfigurationProperties(User.class)
  • 通过 @Autowired 依赖注入 User Bean。
  • 使用 user Bean 的 toString() 方法替换 user() 中的实现

Nacos Config 监听实现 Bean 属性动态刷新

代码实现

@Configuration
@EnableConfigurationProperties(User.class)
public class NacosConfigDemoConfiguration {@Autowiredprivate NacosConfigManager nacosConfigManager;@Autowiredprivate User user;@Value("${user.name}")private String userName;@Value("${user.age}")private int userAge;@Beanpublic ApplicationRunner runner() {return args -> {String dataId = "nacos-config-sample.properties";String group = "DEFAULT_GROUP";nacosConfigManager.getConfigService().addListener(dataId, group, new AbstractListener() {@Overridepublic void receiveConfigInfo(String configInfo) {System.out.println("[Listener] " + configInfo);System.out.println("[Before User] " + user);Properties properties = new Properties();try {properties.load(new StringReader(configInfo));String name = properties.getProperty("user.name");int age = Integer.valueOf(properties.getProperty("user.age"));user.setName(name);user.setAge(age);} catch (IOException e) {e.printStackTrace();}System.out.println("[After User] " + user);}});};}@PostConstructpublic void init() {System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);}@PreDestroypublic void destroy() {System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);}
}

代码主要变化:

  1. @Autowired 依赖注入 NacosConfigManager

  2. 新增 runner() 方法,通过 NacosConfigManagerBean 获取 ConfigService,并增加了 AbstractListener( Listener 抽象类)实现,

    监听 dataId = "nacos-configsample.properties"group = "DEFAULT_GROUP"

重启应用,并将配置 user.age 从 90 调整到 19,观察日志变化:

[Listener] user.name=nacos-config-sampleuser.age= 19
[Before User] User{name='nacos-config-sample', age=90}
[After User] User{name='nacos-config-sample', age=19}

总结

上述三个例子均围绕着 Nacos Config 实现 Bean 属性动态更新,不过它们是 Spring Cloud 使用场景。

如果读者的应用仅使用 Spring 或者 Spring Boot,可以考虑 Nacos Spring 工程,Github 地址:https://github.com/nacos-group/nacos-spring-project,其中 @NacosValue 支持属性粒度的更新。

6、Nacos Config 高级配置

支持自定义 namespace 的配置

例如:

spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7

注:该配置必须放在 bootstrap.properties 文件中

支持自定义 Group 的配置

例如:

spring.cloud.nacos.config.group=DEVELOP_GROUP

支持自定义扩展的 Data Id 配置

一个完整的配置案例如下所示:

spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true

可以看到:

  1. 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的配置方式来支持多个 Data Id 的配置。
  2. 通过 spring.cloud.nacos.config.extension-configs[n].group 的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
  3. 通过 spring.cloud.nacos.config.extension-configs[n].refresh 的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新,感知到最新的配置值。默认是不支持的。

需要注意的点:

  • 多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.extension-configs[n].data-id 其中 n 的值越大,优先级越高
  • spring.cloud.nacos.config.extension-configs[n].data-id值必须带文件扩展名,文件扩展名既可支持 properties,又可以支持 yaml/yml。

清晰案例

# 配置支持共享的 Data Id
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
# 配置 Data Id 所在分组,缺省默认 DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1
# 配置 Data Id 在配置变更时,是否动态刷新,缺省默认 false
spring.cloud.nacos.config.shared-configs[0].refresh=true

配置的优先级

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

A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置

B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置

C: 通过内部相关规则(应用名、应用名 + Profile )自动生成相关的 Data Id 配置(运行参数配置)

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

完全关闭配置

可以通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config

7、Nacos Config Actuator Endpoint

Nacos Config 内部提供了一个 Endpoint, 对应的 Endpoint ID 为 nacos-config,其 Actuator Web Endpoint URI 为 /actuator/nacos-config。

注:使用 Nacos Config Spring Cloud 1.x 版本的话,其 URI 地址则为 /nacos-config

其中,Endpoint 暴露的 json 中包含了三种属性(即服务响应内容):

  1. NacosConfigProperties: 当前应用 Nacos 的基础配置信息。
  2. RefreshHistory: 配置刷新的历史记录。
  3. Sources: 当前应用配置的数据信息
{"NacosConfigProperties":{"serverAddr":"127.0.0.1:8848","username":"","password":"","encode":null,"group":"DEFAULT_GROUP","prefix":null,"fileExtension":"properties","timeout":3000,"maxRetry":null,"configLongPollTimeout":null,"configRetryTime":null,"enableRemoteSyncConfig":false,"endpoint":null,"namespace":null,"accessKey":null,"secretKey":null,"contextPath":null,"clusterName":null,"name":null,"sharedConfigs":null,"extensionConfigs":null,"refreshEnabled":true,"sharedDataids":null,"refreshableDataids":null,"extConfig":null,"configServiceProperties":{"secretKey":"","namespace":"","username":"","enableRemoteSyncConfig":"false","configLongPollTimeout":"","configRetryTime":"","encode":"","serverAddr":"127.0.0.1:8848","maxRetry":"","clusterName":"","password":"","accessKey":"","endpoint":""}},"RefreshHistory":[],"Sources":[{"lastSynced":"2020-09-14 11:11:37","dataId":"nacos-config-sample.properties"},{"lastSynced":"2020-09-14 11:11:37","dataId":"nacos-config-sample"}]
}
rverAddr":"127.0.0.1:8848","maxRetry":"","clusterName":"","password":"","accessKey":"","endpoint":""}},"RefreshHistory":[],"Sources":[{"lastSynced":"2020-09-14 11:11:37","dataId":"nacos-config-sample.properties"},{"lastSynced":"2020-09-14 11:11:37","dataId":"nacos-config-sample"}]
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/213532.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023.12.4 关于 Spring Boot 统一异常处理

目录 引言 统一异常处理 异常全部监测 引言 将异常处理逻辑集中到一个地方&#xff0c;可以避免在每个控制器或业务逻辑中都编写相似的异常处理代码&#xff0c;这降低了代码的冗余&#xff0c;提高了代码的可维护性统一的异常处理使得调试和维护变得更加容易&#xff0c;通…

机器学习之无监督学习:九大聚类算法

今天&#xff0c;和大家分享一下机器学习之无监督学习中的常见的聚类方法。 今天&#xff0c;和大家分享一下机器学习之无监督学习中的常见的聚类方法。 在无监督学习中&#xff0c;我们的数据并不带有任何标签&#xff0c;因此在无监督学习中要做的就是将这一系列无标签的数…

Python实现PDF-Excel

轻松解决PDF格式转Excel&#xff08;使用python实现&#xff09; 实现思路&#xff1a; 要将PDF转换为Excel&#xff0c;可以使用以下步骤&#xff1a; 解析PDF内容&#xff1a;首先&#xff0c;需要使用Python中的第三方库&#xff08;如PyPDF2、pdfminer等&#xff09;来解…

Ribbon 饥饿加载

Ribbon默认是采用懒加载&#xff0c;即第一次访问时才会去创建LoadBalanceClient&#xff0c;请求时间会很长而饥饿加载则会在项目启动时创建&#xff0c;降低第一次访问的耗时&#xff0c;通过下面配置开启饥饿加载: 一、懒加载 Ribbon 默认为懒加载即在首次启动Application…

数据结构之插入排序

目录 前言 插入排序 直接插入排序 插入排序的时间复杂度 希尔排序 前言 在日常生活中&#xff0c;我们不经意间会遇到很多排序的场景&#xff0c;比如在某宝&#xff0c;某东上买东西&#xff0c;我们可以自己自定义价格是由高到低还是由低到高&#xff0c;再比如在王者某…

修改移远提供的GobiNet、quectel-CM源码,使其支持有方N720 4G模块

最近在研究imx6ull linux下4G模块驱动的移植&#xff0c;参考的移远ec20的移植方法&#xff0c;添加了GobiNet驱动&#xff0c;编译了quectel-CM工具&#xff0c;并且可以正常拨号&#xff0c;分配到ip&#xff0c;如下&#xff1a; ping外网也没有压力&#xff0c;如下…

Qt12.8

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…

使用Pytorch实现Grad-CAM并绘制热力图

这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 看一下这个main cnn.py的文件 那这里我为了方便 就直接从官方的torch vision这个库当中导入一些我们常用的model 比如说我这里的例子是采用的mobile net v3 large这个模型 然后这里我将pretrain设…

openEuler 20.03 (LTS-SP2) aarch64 cephadm 部署ceph18.2.0【1】离线部署 准备基础环境

准备3台虚拟机服务器(均可访问公网) 10.2.1.176 &#xff08;作为操作机&#xff09; 10.2.1.191 10.2.1.219 安装基础工具 yum install -y vim 配置hosts 编辑/etc/hosts&#xff0c;添加 10.2.1.176 ceph-176 10.2.1.191 ceph-191 10.2.1.219 ceph-219 配置免密登录…

JVM 执行引擎篇

机器码、指令、汇编语言 机器码 各种用二进制编码方式表示的指令&#xff0c;叫做机器指令码。开始&#xff0c;人们就用它采编写程序&#xff0c;这就是机器语言。机器语言虽然能够被计算机理解和接受&#xff0c;但和人们的语言差别太大&#xff0c;不易被人们理解和记忆&a…

【MySQL语言汇总[DQL,DDL,DCL,DML]以及使用python连接数据库进行其他操作】

MySQL语言汇总[DQL,DDL,DCL,DML] SQL分类1.DDL:操作数据库&#xff0c;表创建 删除 查询 修改对数据库的操作对表的操作复制表&#xff08;重点&#xff09;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 2.DML:增删改表中数据3.DQL&#xff1a;查询表中的记录…

HLS实现图像膨胀和腐蚀运算--xf_dilation和xf_erosion

一、图像膨胀和图像腐蚀概念 我们先定义&#xff0c;需要处理的图片为二值化图像A。图片的背景色为黑色&#xff0c;即像素值为0。图片的目标色为白色&#xff0c;即像素值为1。 再定义一个结构元S&#xff0c;结构元范围内所有的像素为白色&#xff0c;像素值为1。 1、图像的…

RedHat9中安装Mysql8.0+出现“错误:GPG 检查失败“的处理

近期通过VM安装了RedHat9&#xff0c;之后在RedHat9中安装Mysql8.0的时候出现了个问题&#xff1a;“错误&#xff1a;GPG 检查失败”&#xff0c;如图所示&#xff1a; 解决方案&#xff1a;重新导入新的秘钥即可&#xff0c;如下所示&#xff1a; rpm --import https://rep…

连接Redis报错解决方案

连接Redis报错&解决方案 问题描述&#xff1a;Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝&#xff0c;无法连接。 问题原因&#xff1a;redis启动方式不正确 解决方案&#xff1a; 在redis根目录下打开命令行窗口&#xff0c;输入命令redi…

Android studio生成二维码

1.遇到的问题 需要生成一个二维码&#xff0c;可以使用zxing第三方组件&#xff0c;增加依赖。 //生成二维码 implementation com.google.zxing:core:3.4.1 2.代码 展示页面 <ImageViewandroid:id"id/qrCodeImageView"android:layout_width"150dp"an…

公有云迁移研究——AWS Translate

大纲 1 什么是Translate2 Aws Translate是怎么运作的3 Aws Translate和Google Translate的区别4 迁移任务4.1 迁移原因 5 Aws Translate的Go demo6 迁移中遇到的问题6.1 账号和权限问题&#xff1a;6.2 小语种 1 什么是Translate Translate是一种文本翻译服务&#xff0c;它使…

HttpComponents: 领域对象的设计

1. HTTP协议 1.1 HTTP请求 HTTP请求由请求头、请求体两部分组成&#xff0c;请求头又分为请求行(request line)和普通的请求头组成。通过浏览器的开发者工具&#xff0c;我们能查看请求和响应的详情。 下面是一个HTTP请求发送的完整内容。 POST https://track.abc.com/v4/tr…

安卓MediaRecorder(2)录制源码分析

文章目录 前言JAVA new MediaRecorder() 源码分析android_media_MediaRecorder.cpp native_init()MediaRecorder.java postEventFromNativeandroid_media_MediaRecorder.cpp native_setup() MediaRecorder 参数设置MediaRecorder.prepare 分析MediaRecorder.start 分析MediaRec…

目标检测——OverFeat算法解读

论文&#xff1a;OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks 作者&#xff1a;Pierre Sermanet, David Eigen, Xiang Zhang, Michael Mathieu, Rob Fergus, Yann LeCun 链接&#xff1a;https://arxiv.org/abs/1312.6229 文章…

【Flink】Flink核心概念简述

目录 一、Flink 简介二、Flink 组件栈1. API & Libraries 层2. runtime层3. 物理部署层 三、Flink 集群架构四、Flink基本编程模型五、Flink 的部署模式六、Flink 任务的执行模式五、Flink 的优点 一、Flink 简介 Apache Flink 的前身是柏林理工大学一个研究性项目&#x…