分布式配置中心

基本用法#

分布式配置中心解决方案:
国内:

  • 360:Qconf
  • 淘宝: diamond
  • 百度:disconf
    国外:
  • Apache Commons Configuration
  • owner
  • cfg4j

简介#

Spring Cloud Config 是一个发布式系统配置管理的解决方案,它包含了Client和Server。配置文件放在Server端,通过接口的形式提供给Client
Spring Cloud Config主要功能:
集中管理各个环境、各个微服务的配置文件
提供服务端和客户端支持
配置文件修改后,可以快速生效
配置文件通过 Git/SVn 进行管理,天然支持版本回退功能。
支持高并发查询、也支持多种开发语言。

准备工作#

准备工作主要是给GitHub上提交数据
本地配置好相应的配置文件,提交到GitHub

ConfigServer#

首先创建一个ConfigServer工程,创建时添加ConfigServer依赖:

项目创建成功后,项目启动类上添加注解,开启config server功能:

Copy
@SpringBootApplication @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }

然后在配置文件中配置仓库的基本信息:

Copy
spring.application.name=config-server server.port=8082 # 配置文件仓库地址 spring.cloud.config.server.git.uri=https://github.com/snowqwl/configRepo.git # 仓库中,配置文件的目录 spring.cloud.config.server.git.search-paths=client1 # 仓库的用户名密码 spring.cloud.config.server.git.username=2214093189@qq.com spring.cloud.config.server.git.password=

启动项目后,就可以访问配置文件了。访问地址:http://localhost:8082/client1/prod/master

实际上,访问地址有如下规则:
/{application}/{profile}/[{label}]
/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{label}/{application}-{profile}.properties

application表示文件名
profile表示配置文件profile,例如test,dev,prod
label表示git分支,参数可选,默认就是master
接下来,可以修改配置文件,并且重新提交到 GitHub,此时,刷新 ConfigServer 接口,就可以及时看
到最新的配置内容

ConfigClient#

创建一个SpringBoot 项目,添加ConfigClient依赖

项目创建成功后,resources目录下,添加bootstrap.properties配置,内容如下:

Copy
# 下面三行配置,分别对应config-server 中的{application},{profile}以及{label}占位符 spring.application.name=client1 spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.uri=http://localhost:8082 server.port=8083

接下来创建一个HelloController进行测试

Copy
@RestController public class HelloController { @Value("${javaboy}") String javaboy; @GetMapping("/hello") public String hello(){ return javaboy; } }

配置#

使用占位符灵活控制查询目录
修改config-server配置文件

Copy
spring.cloud.config.server.git.search-paths={application}

这里的{application}占位符,表示链接上来的client1的spring.application.name属性的值。
在config-server中,也可以用{profile}表示client的spring.cloud.config.profile,也可以用{label}表示client的spring.cloud.config.label
虽然在实际开发中,配置文件一般放在Git仓库中,但是,config-server也支持将配置文件放在classpath下。
在config-server中添加如下配置:

Copy
# 表示让 config-server 从 classpath 下查找配置,而不是去 Git 仓库中查找 spring.profiles.active=native

也可以在 config-server 中,添加如下配置,表示指定配置文件的位置:

Copy
spring.cloud.config.server.native.search-locations=file:/E:/properties/

配置文件加解密#

常见加密方案#

  • 不可逆加密
  • 可逆加密
    不可逆加密,就是理论上无法根据加密后的密文推算出明文,一般用在密码的加密上,常见的算法如MD5消息摘要算法,SHA安全散列算法。
    可逆加密,看名字就知道可以根据加密后的密文推断出明文的加密方式,可逆加密一般又分为两种:
  • 对称加密
  • 非对称加密
    对称加密指加密的密钥和解密的密钥是一样的,常见算法des,3des,aes
    非对称加密就是加密的密钥和解密的密钥不一样,加密的叫做公钥,可以告诉任何人,解密的叫做私钥,只有自己知道,常见算法:RSA

对称加密#

首先下载不限长度的 JCE:http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip 将下载的文件解压,解压出来的 jar 拷贝到 Java 安装目录中:C:\Program Files\Java\jdk-13.0.1\lib\security
然后,在 config-server 的 bootstrap.properties 配置文件中,添加如下内容配置密钥:

Copy
# 密钥 encrypt.key=javaboy

然后,启动 config-server ,访问如下地址,查看密钥配置是否OK:http://localhost:8082/encrypt/status

然后,访问:http://localhost:8082/encrypt ,注意这是一个 POST 请求,访问该地址,可以对一段明文进行加密。把加密后的明文存储到 Git 仓库中,存储时,要注意加一个 {cipher} 前缀。


提交到github上

非对称加密#

非对称加密需要我们首先生成一个密匙对。
在命令行执行如下命令,生成keystore

Copy
keytool -genkeypair -alias config-server -keyalg RSA -keystore D:\springcloud\config-server.keystore

命令执行完成后,拷贝生成的keystore文件到config-server的resources目录下。
然后在config-server的bootstrap.properties目录中,添加如下配置:

Copy
encrypt.key-store.location=config-server.keystore encrypt.key-store.alias=config-server encrypt.key-store.password=111111 encrypt.key-store.secret=111111

重启 config-server ,测试方法与对称加密一致。
注意,在 pom.xml 的 build 节点中,添加如下配置,防止 keystore 文件被过滤掉。

Copy
<resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.keystore</include> </includes> </resource> </resources>


安全管理#

防止用户直接访问config-server看到配置文件内容,我们可以用spring security来保护config
首先在config-server中添加spring security依赖

Copy
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.3.2.RELEASE</version> </dependency>

添加完依赖后,config-server接口就自动被保护起来了。
默认自动生成的密码不好记,所以我们可以在config-server中,自己配置用户名和密码。
在config-server的配置文件中,添加如下配置,固定用户名密码:

Copy
spring.security.user.name=javaboy spring.security.user.password=123

然后在config-client的bootstrap.properties配置文件中,添加如下配置:

Copy
spring.cloud.config.username=javaboy spring.cloud.config.password=123

服务化#

前面的配置都是直接在config-client中写死config-server的地址
首先启动Eureka.然后,为了让config-server和config-client能注册到Eurake,给它两添加如下依赖:

Copy
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>

然后,在application.properties配置文件中配置注册信息。

Copy
eureka.client.service-url.defaultZone=http://localhost:1111/eureka

然后,修改config-client的配置文件,不再直接写死config-server的地址了。

Copy
# 下面三行配置,分别对应 config-server 中的 {application}、{profile}以及{label}占位符 spring.application.name=client1 spring.cloud.config.profile=dev spring.cloud.config.label=master #spring.cloud.config.uri=http://localhost:8081 # 开启通过 eureka 获取 config-server 的功能 spring.cloud.config.discovery.enabled=true # 配置 config-server 服务名称 spring.cloud.config.discovery.service-id=config-server server.port=8082 spring.cloud.config.username=javaboy spring.cloud.config.password=123 eureka.client.service-url.defaultZone=http://localhost:1111/eureka

注意,加入 eureka client 之后,启动 config-server 可能会报错,此时,我们重新生成一个 jks 格式的
密钥。

Copy
keytool -genkeypair -alias mytestkey -keyalg RSA -keypass 111111 -keystore D:\springcloud\config-service.jks -storepass 111111

生成之后,拷贝到 configserver 的 resources 目录下,同时修改 bootstrap.properties 配置。

Copy
# 密钥 #encrypt.key=javaboy encrypt.key-store.location=classpath:config-service.jks encrypt.key-store.alias=mytestkey encrypt.key-store.password=111111 encrypt.key-store.secret=111111 spring.security.user.name=javaboy spring.security.user.password=123

同时也修改一个pom.xml中的过滤条件

Copy
<resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.jks</include> </includes> </resource> </resources>


动态刷新#

当配置文件发生变化之后,config-server 可以及时感知到变化,但是 config-client 不会及时感知到变化,默认情况下,config-client 只有重启才能加载到最新的配置文件。
首先给 config-client 添加如下依赖:

Copy
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.3.3.RELEASE</version> </dependency>

然后,添加配置,使 refresh 端点暴露出来:

Copy
management.endpoints.web.exposure.include=refresh

最后,再给 config-client 使用了配置文件的地方加上 @RefreshScope 注解,这样,当配置改变后,只需要调用 refresh 端点,config-client 中的配置就可以自动刷新。

Copy
@RestController @RefreshScope public class HelloController { @Value("${javaboy}") String javaboy; @GetMapping("/hello") public String hello(){ return javaboy; } }

重启 config-client,以后,只要配置文件发生变化,发送 POST 请求,调用 http://localhost:8082/actu
ator/refresh 接口即可,配置文件就会自动刷新。

请求失败重试#

config-client 在调用 config-server 时,一样也可能发生请求失败的问题,这个时候,我们可以配置一个请求重试的功能。
要给 config-client 添加重试功能,只需要添加如下依赖即可:

Copy
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.2.5.RELEASE</version> </dependency>

然后,修改配置文件,开启失败快速响应。

Copy
# 开启失败快速响应 spring.cloud.config.fail-fast=true

然后,注释掉配置文件的用户名密码,重启 config-client,此时加载配置文件失败,就会自动重试。

也可以通过如下配置保证服务的可用性:

Copy
# 开启失败快速响应 spring.cloud.config.fail-fast=true # 请求重试的初识间隔时间 spring.cloud.config.retry.initial-interval=1000 # 最大重试次数 spring.cloud.config.retry.max-attempts=6 # 重试时间间隔乘数 spring.cloud.config.retry.multiplier=1.1 # 最大间隔时间 spring.cloud.config.retry.max-interval=2000
posted @   柒丶月  阅读(277)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示
CONTENTS