前言
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。
在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。
在spring cloud config 组件中,分两个角色,一是config server,二是config client。
Config Server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置文件内容,也可以使用SVN存储,或者是本地文件存储。
Config Client是Config Server的客户端,用于操作存储在Config Server中的配置内容。
微服务在启动时会请求Config Server获取配置文件的内容,请求到后再启动容器。
一、简介
1、Spring Cloud Config 项目
-
提供 服务端 和 客户端 支持
-
集中式 管理分布式环境下的应用配置
-
基于 Spring 环境,无缝 与 Spring 应用集成
-
可用于 任何 语言开发的程序
-
默认实现基于 git 仓库,可以进行 版本管理
-
可替换 自定义实现
2、Spring Cloud Config Server 作为配置中心服务端
-
拉取配置时更新 git 仓库副本,保证是最新结果
-
支持数据结构丰富,yml, json, properties 等
-
配合 eureke 可实现服务发现,配合 cloud bus 可实现配置推送更新
-
配置存储基于 git 仓库,可进行版本管理
-
简单可靠,有丰富的配套方案
3、Spring Cloud Config Client 默认客户端实现
-
SpringBoot 项目不需要改动任何代码,加入一个启动配置文件指明使用 ConfigServer 上哪个配置文件即可
二、服务端
1、准备配置
https://gitee.com/pingfanrenbiji/spring-cloud-repo.git
2、创建maven config-server 并添加依赖
3、创建启动类,并加上开启Config服务端注解@EnableConfigServer
4、添加application属性文件
5、启动项目 简单测试
a、启动状态
localhost:9000/application/dev
localhost:9000/application-dev.properties
b、访问规则
/{appication}/{profile}/[{label}]
/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties/{label}/{application}-{profile}.yml
它们都可以映射到对应的配置文件{application}-{profile}.properties
其中{label}为具体的分支,默认为master;
6、配置中心的安全认证
现在配置内容通过加解密的方式实现了安全保障,
但是配置中心spring-cloud-config-server还是完全对外公开的。
如果通过http协议地址:http://config-server-ip:port/applicationName/profile/label
是可以获取到配置文件内容,这对配置信息的安全保护还是不足。
需要给spring-cloud-config-server提供用户安全认证,
在这里使用spring-boot提供的security组件来使用HTTP Bastic用户安全认证。
在spring-cloud-config-server中增加新的依赖security:
在spring-cloud-config-server全局配置文件中增加用户信息:
这样就为spring-cloud-config-server提供了用户安全认证。
在客户的bootstrap配置文件中增加下述内容,来实现spring-cloud-config-client访问
7、配置中心加密
配置文件统一存储在GIT中,虽然增强了管理和版本控制,但是文件内容的安全性也成了问题。
如果外部任意知道了GIT地址或spring-cloud-config-server的地址,那么配置文件的全部内容相当于
对外完全开放。这个时候就需要提供配置内容加解密逻辑。
将加密后的配置内容保存在GIT仓库中,在spring-cloud-config-client访问
spring-cloud-config-server的时候,过spring-cloud-config-server实现加密数据的解密,
这样就可以保证配置内容的安全了。
a、对称加密
配置密钥
查看加解密环境
对dev-5.0.0加密
在命令行执行
curl http://127.0.0.1:9000/encrypt -u test -d dev-5.0.0
Enter host password for user 'test':
dcd8d3714c6e8fe91660b73461352a7807b6938e48e9d17773e6f8714cad718d(base)
-d指加密数据
-u是用户名
将密文配置到git文件中去
密文前面要加上{cipher}
访问该配置得到明文
b、非对称加密
使用不同的密钥(key)实现配置数据的加密和解密。
使用公钥加密数据,使用私钥解密数据。
JDK提供了java-keytool工具来生成密钥,生成的密钥信息是"keystore"文件。
keytool工具使用方式如下:
keytool -genkeypair -alias "test" -keyalg "RSA"
-keystore "test.keystore"
生成keystore
将生成的密钥文件test.keystore保存到spring-cloud-config-server的
classpath下(src/main/resources),并在全局配置文件中增加下述内容:
实现配置数据的加解密方式和对称加密一致。
三、客户端
1、创建Maven项目 config-client,添加依赖
2、创建一般启动类即可,无需添加注解,创建Controller,为测试做准备
3、为了更明显的测试Config是否生效,在application配置文件中添加:
4、配置优先级
添加bootstrap.properties配置文件,bootstrap.properties为默认文件名,
在springcloud中配置文件有个优先级的概念,
当本地application.properties文件和bootstrap.properties文件中配置了同样的属性不同的值,由于bootstrap的优先级高,
则在bootstrap中的属性不会被application中的覆盖,反而会覆盖掉application中的配置
5、测试
先启动服务器,再启动客户端,观察端口和页面,由于前面在application中添加了端口为9001,而远程仓库的配置文件中也添加了端口9999
这样就实现了基本的远程配置仓库了,但是一旦有文件更改还得重新启动项目,这样就很有问题了,所以需要刷新,使用/refresh端点刷新:
a、在application或远程文件中添加:
b、在controller上添加注解@RefreshScope注解:
c、启动测试,打开,修改version=dev-4.0.0为version=dev-5.0.0,并发送刷新请求http://localhost:9999/refresh,刷新测试页面查看:
6、多配置文件加载
四、SpringCloud Bus自动刷新配置
Spring Cloud Bus集成了市面上常见的RabbitMQ和Kafka等消息代理。
其会连接微服务系统中所有拥有Bus总线机制的节点,当有数据变更的时候,会通过消息中间件使用消息广播的方式通知所有的微服务节点同步更新数据。(如:微服务配置更新等)
基于client端实现全局刷新
基于server和client端实现全局刷新 将热刷新逻辑和具体的服务应用解耦
1、需要先安装rabbitmq
a、docker pull rabbitmq:management
b、docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
c、默认账号:guest/guest
2、基于端点刷新的项目 添加依赖
3、在bootstrap中增加RabbitMQ的配置:
4、读取配置
5、端口配置
6、启动 config-bus-client测试,打开,修改version=dev-4.0.0为version=dev-5.0.0,并发送刷新请求http://localhost:9002/bus/refresh,刷新测试页面查看:
7、通过gitee或git的weblook 主动推送配置变动信息
局部刷新服务
使用Bus总线也可以实现部分服务热刷新。
前文讲到的两种刷新实现方式都是全局热刷新,所有带有Bus消息总线组件且与同一个RabbitMQ连接的微服务应用都会执行热刷新逻辑。
有些时候,热刷新只需要在一个微服务应用或一个微服务应用集群中执行,这个时候就需要使用局部刷新功能。
局部热刷新的实现过程和全局热刷新一致,只是请求地址/bus/refresh需要提供一个GET请求参数,请求参数命名为destination,参数值是要刷新的微服务名称:端口[**]。
如:微服务名:config-client 微服务端口:10802、10803、10804
如果只热刷新微服务config-client:10802时,请求的路径为/bus/refresh?destination=config-client:10802。
如果需要刷新config-client微服务集群,则请求路径为/bus/refresh?destination=config-client:**
五、参考资料
源码地址:
https://gitee.com/pingfanrenbiji/springcloud-example.git
参考网址:
https://www.cnblogs.com/lfalex0831/p/9206605.html
https://www.cnblogs.com/jing99/p/11720834.html
网友评论