述
上文中我们了解了分布式配置中心Spring Cloud Config的一个基本的使用,那么本文就来详细的了解一下Spring Cloud Config,它里面的一些配置细节以及工作流程等
工作流程
上图就是Config Server的一个大致的工作流程.
首先,需要一个远程的Git仓库,我们在写demo的时候可以直接使用github,在实际生产环境中是需要有一个Git服务器的,Git仓库主要就是用来保存我们的配置文件的.
除了远程的Git仓库之外,还需要一个本地的Git仓库,每次Config Server访问远程Git仓库时,都会在本地保存一份,当远程仓库挂掉或者无法访问的情况下,就是用本地仓库中的配置信息.
图中的service A B就是我们的微服务具体应用,这些应用启动的时候就会从Config Server中加载相应的配置信息
当微服务A/B尝试去从Config Server中加载配置信息的时候,Config Server会先通过git clone命令克隆一份配置文件保存到本地
配置文件是存储在Git仓库中,所以配置文件天然的具备版本管理功能,Git中的Hook功能可以实时监控配置文件的修改.
Git URI中的占位符
假设我们有两个微服务应用A和B,两个应用的配置文件分别放在git仓库中的两个文件夹中,比如https://github.com/zhouze-java/spring-cloud-demo-config/a
和https://github.com/zhouze-java/spring-cloud-demo-config/b
,两个文件夹中,但是我们的Config Server是只有一个的,那么当 A和B两个应用连接上Config Server的时候Config Server怎么知道去哪里取配置文件,那这个时候就可以使用占位符来处理这种情况了.
上文中,我们已经使用过{application},{profile},{label}这三个占位符了,这些占位符除了用来标识配置文件的规则,还可以用在Config Server中对Git仓库的URI配置,用在URI配置中时,这三个占位符分别代表的含义如下:
- {application}映射到客户端的 spring.application.name
- {profile}映射到客户端上的 spring.profiles.active
- {label}这是一个服务器端功能,标记”版本”的配置文件集
举个例子. 假设我不同环境的配置文件分别放在以下目录中:
https://github.com/zhouze-java/spring-cloud-demo-config/application/dev
https://github.com/zhouze-java/spring-cloud-demo-config/application/test
https://github.com/zhouze-java/spring-cloud-demo-config/application/prod
然后客户端的文件是这样配置的:1
2
3
4
5
6
7
8spring:
application:
name: application
cloud:
config:
profile: dev
label: master
uri: http://localhost:2007/
然后,在config server中按以下方式配置就可以了:1
2
3
4
5
6
7
8
9
10
11spring:
application:
name: config-server
cloud:
config:
server:
git:
# uri表示配置中心所在仓库的位置
uri: https://github.com/zhouze-java/spring-cloud-demo-config.git
# search-paths表示仓库下的子目录
search-paths: {application}/{profile}
这种存储方式不一定好用,这里只展示占位符的用法.
在默认情况下,Config Server从远程仓库 clone下来的文件保存在C:\Users\<当前用户>\AppData\Local\Temp目录下,我们可以通过如下配置来修改:1
2
3
4
5
6spring:
cloud:
config:
server:
git:
basedir: D:\\xxx\\
健康监测机制
默认情况下Spring Cloud Config会为配置中心服务端创建一个健康监测器,该检测器默认情况下是访问的仓库文件是{application}为app的配置文件,如果仓库中不存在这个文件,健康显示器就会显示仓库无法连接.
此时有以下两种解决方案:
- 向仓库中添加相应的配置文件.
- 重新指定检测的配置
重新指定检测的配置文件,需要在服务端做出如下配置.1
2
3
4
5
6
7
8
9
10
11
12spring:
application:
name: config-server
cloud:
config:
server:
health:
repositories:
check:
name: application
label: master
profiles: dev
安全性
在开发中,我们的配置中心肯定是不能被随便访问的, 我们可以给开发中心加一个密码,我们的项目是spring boot为基础的,所以可以直接整合Spring Security,具体步骤如下:
首先需要引入security的依赖:1
2
3
4
5<!-- serurity -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后再配置文件中配置用户名和密码:1
2
3
4security:
user:
name: root
password: 123456
最后 在配置中心的客户端也配置好用户名密码就好了,还是在bootstrap.yml中配置,配置如下:1
2
3
4
5spring:
cloud:
config:
username: root
password: 123456
配置完成之后就ok了.
加解密
在微服务架构中,由于独立的服务多,加上前期测试工作量大,一些原本由运维人员维护的敏感信息会被我们直接写在微服务中,以提高开发效率,但是这种明文存储方式显然是非常危险的,所以我们要对这些信息进行加密,而Spring Cloud Config则提供了对称加解密/非对称加解密的功能来帮助我们完成这一需求
接下来就看一下具体如何实现
JCE下载
默认情况下JRE中自带了JCE,但默认是一个有限长度的版本,我们这里需要一个不限长度的版本,可以从Oracle官网中下载,内容如下
然后把这两个jar放到%JAVA_HOME%\jre\lib\security
这个目录下,覆盖原来的文件即可.
版本修改
Spring Cloud的Dalston.SR3和Dalston.SR2版本在这个问题上是有BUG的,如果用这两个版本在这里测试会没有效果,应该避开使用这两个版本,我这里使用的是Dalston.SR4版本
对称加解密
这个比较简单,直接配置密钥就可以了,在我们的config-server工程中配置,这个密钥的配置是需要放到bootstrap.yml里面的1
2encrypt:
key: testKey
配置完成之后,启动项目,然后访问http://localhost:2007/encrypt/status,如果看到以下结果,就表示配置成功了
然后用postman去测试一下,需要先把config-server中security的验证先去掉,然后用postman访问/encrypt和/decrypt接口去加解密,比如要给”dev”这个字符串加密,方式如下:
解密方式如下:
当我们拿到加密的字符串后,就可以在配置文件中使用了,比如之前的配置文件application-dev.yml,改成以下内容:1
sang: '{cipher}9b7d72b9506c758b86d7e94f39606f3cd4bea122e11a6a45428506833ce260fe'
配置文件中,值如果是以{cipher}
开头,表示这个值是一个加密的字符串,配置中心获取到这个值之后,会先进行解密,然后再返回给客户端使用.
修改完配置文件之后,启动config-server和config-client,然后访问我们之前的接口http://localhost:2008/test3, 返回如下:
可以看到,我们在客户端获取到的配置是解密后的字符串
非对称加密
上面我们用的是对称加密的方式来保证配置文件的安全性,如果使用非对称的加解密的方式,那安全性就更高了,下面看一下具体怎么使用.
首先需要生成密钥对,用jdk中自带的keytools工具,方式如下:
先打开cmd,然后运行以下命令1
keytool -genkeypair -alias config-server -keyalg RSA -keystore config-server.keystore
然后输入口令,其他地方回车,最后确定,如下:
执行成功之后,会在执行目录下面生成一个config-server.keystore文件,然后复制到config-server的src\main\resources目录下,然后还是在bootstrap.yml中做如下配置:1
2
3
4
5
6encrypt:
key-store:
location: config-server.keystore
alias: config-server
password: 123456
secret: 123456
ok,到这里非对称加密就配置好了,然后去测试一下,和非对称的加密的测试方式是一样的
加密:
解密:
最后修改配置文件:
然后可以提交配置文件,启动项目去测试一下