Spring Cloud-19-分布式配置中心服务端配置细节

上文中我们了解了分布式配置中心Spring Cloud Config的一个基本的使用,那么本文就来详细的了解一下Spring Cloud Config,它里面的一些配置细节以及工作流程等

工作流程

image

上图就是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/ahttps://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
8
spring:
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
11
spring:
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
6
spring:
cloud:
config:
server:
git:
basedir: D:\\xxx\\

健康监测机制

默认情况下Spring Cloud Config会为配置中心服务端创建一个健康监测器,该检测器默认情况下是访问的仓库文件是{application}为app的配置文件,如果仓库中不存在这个文件,健康显示器就会显示仓库无法连接.

此时有以下两种解决方案:

  1. 向仓库中添加相应的配置文件.
  2. 重新指定检测的配置

重新指定检测的配置文件,需要在服务端做出如下配置.

1
2
3
4
5
6
7
8
9
10
11
12
spring:
application:
name: config-server
cloud:
config:
server:
health:
repositories:
check:
name: application
label: master
profiles: dev

此时重启应用,访问http://localhost:2007/application/dev/master,如果能访问到,那就说明已经连接上了,而且访问http://localhost:2007/health,会返回`{"status":"UP"}`

安全性

在开发中,我们的配置中心肯定是不能被随便访问的, 我们可以给开发中心加一个密码,我们的项目是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
4
security:
user:
name: root
password: 123456

最后 在配置中心的客户端也配置好用户名密码就好了,还是在bootstrap.yml中配置,配置如下:

1
2
3
4
5
spring:
cloud:
config:
username: root
password: 123456

配置完成之后就ok了.

加解密

在微服务架构中,由于独立的服务多,加上前期测试工作量大,一些原本由运维人员维护的敏感信息会被我们直接写在微服务中,以提高开发效率,但是这种明文存储方式显然是非常危险的,所以我们要对这些信息进行加密,而Spring Cloud Config则提供了对称加解密/非对称加解密的功能来帮助我们完成这一需求

接下来就看一下具体如何实现

JCE下载

默认情况下JRE中自带了JCE,但默认是一个有限长度的版本,我们这里需要一个不限长度的版本,可以从Oracle官网中下载,内容如下
image
然后把这两个jar放到%JAVA_HOME%\jre\lib\security这个目录下,覆盖原来的文件即可.
image

版本修改

Spring Cloud的Dalston.SR3和Dalston.SR2版本在这个问题上是有BUG的,如果用这两个版本在这里测试会没有效果,应该避开使用这两个版本,我这里使用的是Dalston.SR4版本

对称加解密

这个比较简单,直接配置密钥就可以了,在我们的config-server工程中配置,这个密钥的配置是需要放到bootstrap.yml里面的

1
2
encrypt:
key: testKey

配置完成之后,启动项目,然后访问http://localhost:2007/encrypt/status,如果看到以下结果,就表示配置成功了

image

然后用postman去测试一下,需要先把config-server中security的验证先去掉,然后用postman访问/encrypt和/decrypt接口去加解密,比如要给”dev”这个字符串加密,方式如下:
image

解密方式如下:
image

当我们拿到加密的字符串后,就可以在配置文件中使用了,比如之前的配置文件application-dev.yml,改成以下内容:

1
sang: '{cipher}9b7d72b9506c758b86d7e94f39606f3cd4bea122e11a6a45428506833ce260fe'

配置文件中,值如果是以{cipher}开头,表示这个值是一个加密的字符串,配置中心获取到这个值之后,会先进行解密,然后再返回给客户端使用.

修改完配置文件之后,启动config-server和config-client,然后访问我们之前的接口http://localhost:2008/test3, 返回如下:
image
可以看到,我们在客户端获取到的配置是解密后的字符串

非对称加密

上面我们用的是对称加密的方式来保证配置文件的安全性,如果使用非对称的加解密的方式,那安全性就更高了,下面看一下具体怎么使用.

首先需要生成密钥对,用jdk中自带的keytools工具,方式如下:

先打开cmd,然后运行以下命令

1
keytool -genkeypair -alias config-server -keyalg RSA -keystore config-server.keystore

然后输入口令,其他地方回车,最后确定,如下:
image

执行成功之后,会在执行目录下面生成一个config-server.keystore文件,然后复制到config-server的src\main\resources目录下,然后还是在bootstrap.yml中做如下配置:

1
2
3
4
5
6
encrypt:
key-store:
location: config-server.keystore
alias: config-server
password: 123456
secret: 123456

ok,到这里非对称加密就配置好了,然后去测试一下,和非对称的加密的测试方式是一样的

加密:
image
解密:
image

最后修改配置文件:
image

然后可以提交配置文件,启动项目去测试一下