Spring Cloud Config
分布式配置中心解决方案
国内:
- 360: QConf
- 淘宝:diamond
- 百度:disconf
国外:
- Apache Commons Configuration
- owner
- cfg4j
但是都不如 Spring Cloud Config 强大,因为它与 Spring 家族融合最好。
Spring Cloud Config 简介
Spring Cloud Config 是一个分布式系统配置管理的解决方案。它包含了 Client 和 Server。配置文件放在 Server 端,通过接口的形式提供给 Client。
Spring Cloud Config 主要功能:
- 集中管理各个环境、各个微服务的配置文件
- 提供服务端和客户端的支持
- 配置文件修改后,可以快速生效
- 配置文件通过 Git/SVn 进行管理,天然支持版本回退功能
- 支持高并发查询、同时支持多种开发语言
Spring Cloud Config 学习
Spring Cloud Config 准备工作
准备工作主要是给 Github 上提交数据。
- 首先在本地创建好相应的配置文件,我们在本地新建了一个 configRepo 文件夹,里面的单个文件夹代表一个服微务,服务文件夹里面是测试上传的 .properties 文件。
- 提交到 Github 上
ConfigServer 搭建
ConfigServer 从 GitHub 上加载数据的配置文件,加载到配置文件之后,以接口的形式提供给 ConfigClient。
- 首先创建一个 ConfigServer 工程,创建时添加 ConfigServer 依赖。
- 在启动类上添加 @EnableConfigServer 注解,开启配置服务器功能。
- 配置 application.yml,配置仓库的基本信息。
- 访问测试: http://localhost:8081/client1/dev/main 或者 http://localhost:8081/client1-dev.yml 或者 http://localhost:8081/client1-dev.properties ,控制台中会显示,在 github 中会克隆一份文件到本地的临时目录中。
- 启动项目后,就可以访问配置文件了。
访问地址有规则:
- /{application}/{profile}/[{label}]
- /{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.yml
- /{label}/{application}-{profile}.properties
application 表示配置文件名
profile 表示配置文件 profile,例如 dev、test、prod
label 表示 git 分支,参数可选,默认是 master
接下来可以修改配置文件,并且重新提交到 Github,此时,刷新 ConfigServer 接口,就可以及时看到最新的配置内容。
ConfigClient 搭建
- 首先创建一个 spring boot 项目,添加 ConfigClient 依赖。
- 创建成功后,在 resources 目录下,添加 bootstrap.yml 配置文件。
- 配置 bootstrap.yml。
- 接下来创建一个 HelloController 进行测试。
ConfigServer 简单配置
使用占位符灵活控制查询目录:
- 修改 config-server 配置文件,将写死的 client1 改为 {application}。这里的 {application} 占位符,表示链接上来的 client1 的 spring.application.name 属性的值。
- 可以使用 {profile} 表示 client 的 spring.cloud.config.profile,也可以使用 {label} 表示 client 的 spring.cloud.config.label
虽然在实际开发中,配置文件一般都是放在 git 仓库中,但是 config-server 也支持将配置文件放在 classpath 下。(仅作为了解,实际开发不推荐)
- 将配置好的文件复制到 resources 目录下。
- 在 application.yml 下添加配置 spring.profiles.active=native,表示让 config-server 从 classpath 下查找配置,而不是去 Git 仓库上查找。
- 随便修改一下配置文件,然后重启 config-client、config-server 服务,重新访问测试接口返回。
Config 配置文件加密和解密
常见的加密方案
不可逆加密
不可逆加密就是理论上无法根据加密后的密文推算出明文,像加密的框架 Shiro(MD5、SHA) 、Spring Security 都是采用这种方式,一般使用在密码加密上,常见的算法:
- MD5 消息摘要算法
- SHA 安全散列算法
可逆加密
可逆加密就是可以根据加密后的密文推断出明文的加密方式,可逆加密一般又分为两种:
对称加密
对称加密指的是加密的密钥和解密的密钥是一样的,常见的算法并随顺序强度逐渐升级:
- des
- 3des
- aes
首先下载不限长度的 JCE:https://www.oracle.com/java/technologies/javase-jce8-downloads.html
macOS 中 Java 安装包地址:/Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home/jre/lib/security/policy
- 将两个.jar 包复制到 jre 目录下。
- 然后在 config-server/resources 目录下,添加 bootstrap.yml 配置文件,并且配置密钥。
- 启动 config-server 后,访问 http://localhost:8081/encrypt/status , 查看密钥配置是否成功,返回 200 即为成功。
- 然后使用测试工具 Apifox 中 POST 请求 http://localhost:8081/encrypt ,这个接口请求的方式是 post,请求的 body 应该以 json 的形式写到 raw 里面,可以对一段明文进行加密,把加密后的明文存储到 Git 仓库。
- 存储时候注意需要在密文前添加 {cipher} 前缀,表示这一段数据是密文,而不是一段普通的字符串。
非对称加密
非对称加密指的是加密的密钥和解密的密钥不一样,加密的称之为公钥,可以告诉任何人,解密的称之为私钥,只能自己知道,比如 Github 的验证、支付宝的支付开发,一对多的场景一般都使用用非对称加密。常见的算法:
- RSA
1. 非对称加密我们首先需要生成一个密钥对。
2. 在命令行执行命令,生成 keystore: keytool -genkeypair -alias "config-server" -keyalg RSA -keystore "/Users/sihai/Object/Spring Cloud/Eureka/config-server.keystore" 3. 命令执行完成后,拷贝生成的 keystore 文件到 config-server 的 resources 目录下。
4. 然后在 config-server 的 bootstrap.yml 中添加非对称加密配置。
5. 注意,还需要在 pom.xml 的 build 节点中,添加配置,防止 keystore 被过滤掉。
6. 启动 config-server 后,访问 http://localhost:8081/encrypt/status , 查看密钥配置是否成功,返回 200 即为成功。
7. 然后使用测试工具 Apifox 中 POST 请求 http://localhost:8081/encrypt ,这个接口请求的方式是 post,请求的 body 应该以 json 的形式写到 raw 里面,可以对一段明文进行加密,把加密后的明文存储到 Git 仓库。
8. 存储时候注意需要在密文前添加 {cipher} 前缀,表示这一段数据是密文,而不是一段普通的字符串。
configServer 安全管理
防止用户可以直接访问 config-server 看到配置文件内容,我们可以用 spring security 来保护 config-server 接口。
- 既然我们需要使用 spring security,那么就需要先在 config-server 中添加其依赖。只要添加了依赖,你的接口就已经会被保护。
- 由于 security 的用户名密码不好记,所以我们可以分别在 config-server、config-client 配置文件中自定义,固定用户名密码。
Config 配置服务化
前面的配置都是直接在 config-client 中写死了 config-server 的地址,我们需要注册到 eureka 中,相互调用地址。
- 启动 Eureka。
- 在 client、server 中添加 Eureka 依赖。
- 在 application.yml 配置文件中配置注册信息,为了 config-client 不再直接写死 config-server 的地址,同时注释掉 client 中 config.uri 的地址。
注意:加入了 eureka client 之后,启动 config-server 可能会报错,这个时候,我们可以重新生成另一个 jks 格式的密钥。
keytool -genkeypair -alias "mytestkey" -keyalg RSA -keypass 111 -keystore "/Users/sihai/Object/Spring Cloud/Eureka/config-server.jks" -storepass 111
然后复制到 config-server 下的 resources 目录下,修改配置文件,修改 location、alias 配置。同时需要修改 pom.xml 过滤条件。
config 配置动态刷新
当配置文件发生了改变之后,config-server 可以及时的感知到了变化,但是 config-client 不可以及时的感知到,在默认情况下,config-client 只有重启才能加载到最新的配置文件,很不方便,我们需要做到不重启 config-client 也可以重新加载到配置文件。
- 首先给 config-client 添加 actuator 依赖。
- 添加配置,使 refresh 端点暴露出来。
- 再给 config-client 使用了配置文件的地方加上 @RefreshScope 注解,这样的话,当配置发生了改变之后,只需要调用 refresh 端点,config-client 中的配置就可以实现自动刷新。
- 重启 config-client,只要配置文件发生改变,访问 POST 请求的 http://localhost:8082/actuator/refresh ,调用一下这个端点后,重新请求 http://localhost:8082/hello ,就会自动刷新过来。
Config 解决请求发送失败重试
config-client 在调用 config-server 时,也一样有可能会发生请求失败的问题。这个时候,我们可以配置一个请求重试的功能。
- 需要给 config-client 添加重试功能,只需要添加 retry、aop 即可。
- 添加了 retry 之后,这个服务就已经具备了重试功能。
- 然后需要修改配置,开启失败快速响应。
- 如果注释掉配置文件中的 security 用户名密码,重启 config-client,此时加载配置的失败,就会自动重试。
- 也可以通过 config.retry 中的配置,来保证服务的可用性。