要做好微服务的配置管理,则需要处理好以下几个问题:
- 在微服务架构中配置数据与服务实例不要在同一个地方,最好各自独立分开。
- 解决非侵入式配置数据的植入
- 通过对配置文件的集中式管理,可以非常方便地对微服务的配置进行统一修改和发布,并能够建立版本机制,以便后续进行配置数据的回溯。
-
Spring Cloud Config简介
SpringCloud Config核心就是配置中心,通过一个服务端和多个客户端实现配置服务。具有中心化、版本控制、支持动态更新和语言独立等特性,其优点:
提供配置服务器和配置客户端两种角色,便于部署和使用,使开发者可以集中管理分布式环境下的应用配置。
- 配置服务器集中对配置资源进行管理,并支持多种配置资源存储方式,如Git、SVN及文件系统。
- 通过对Git、SVN的支持,便于对配置文件进行版本管理,可以对配置文件的变更做审查。
- 应用通过简单的注解就可以实现配置的统一管理。
- Spring Cloud Config提供与Spring Boot配置类似的机制,可以非常容易地实现对应用开发环境、测试环境、灰度环境和生产环境的配置、切换和迁移等处理。
- 配置服务器可以方便地与Eureka和Consul等进行整合,快速构建一个高可用的配置服务。
- 配置服务器也可以用于其他语言开发的服务中。
Spring Cloud Config有两个角色Server和Client。
Server作为配置中心的服务端作用:
- 当配置客户端获取配置时,服务端及时从Git仓库中获取配置副本,从而保证配置数据为最新。
- 支持从yml、json、properties等文件加载配置
- 配置Eureka可实现服务发现,配置Cloud Bus可实现配置推送更新
- 默认配置存储基于Git,从而支持配置的版本管理。
Client只需要在引导配置文件中声明所使用的配置服务器地址即可。
快速启动
1、构建配置服务器
编写pom文件
编写启动类
编写配置文件
2、创建应用配置文件
productservice.yml
productservice-dev.yml
测试
3、升级微服务配置
对用户、商品微服务增加依赖项
增加bootstrap.yml配置,application.yml的配置全部注释掉
4、启动测试
依次启动Eureka、Config、User和Producet服务。
当我们启动ProducetService时,Config相关代码将根据bootstrap.yml所配置的服务名称和所要启动的profile向配置服务器的端点请求配置数据。配置服务器在收到请求后,根据对应的参数,从配置资源库加载相应的配置文件,然后根据这些配置文件构建数据,并传给配置客户端,最后根据获得的配置数据来构建应用上下文。
5、@Value注解
验证@Value注解获取cofig配置中心的配置属性
6、Spring配置加载顺序
一个Spring Boot应用,可以通过多种方式进行配置。
- 命令行参数:使用—xxx=xxx格式在启动时传递,比如—server.port=2000
- 从java:comp/env加载的JNDI属性
- Java系统属性:通过-Dxxx=xxx格式设置,优先级比上面的配置低。
- 操作系统环境变量
- RandomValuePropertySource:使用random.*属性进行配置,主要是在系统配置中需要使用随机数的地方使用,如abc.securityid=${random.value}。
- 特定应用的properties或yml配置文件:这些文件名称的格式为application-{profile}.properties或yml,通过指定使用的profile来加载。
- 应用配置文件application.properties或yml:默认加载的配置文件,通过上面的配置可以配属属性的覆盖。
@Configuration、@PropertySource或@ConfigurationProperties所指向的配置文件,@ConfigurationProperties可以批量的将配置注入到Bean中。
配置资源库
1、配置资源规则详解
Spring Cloud Config是通过EnvironmentRepository来获取Environment对象解决的。该对象是对Spring的Environment(包括做为主要配置属性的propertySources)对象的浅拷贝。在加载Environment相应资源时参数变化成了以下变量:{application}:对应客户端配置中的spring.application.name。
- {profile}:对应客户端配置中的spring.profiles.action。
- {label}:对应配置服务端锁配置的spring.cloud.config.label。
- 当配置客户端启动时,根据bootstrap.yml中配置的应用名称(spring.application.name)、环境名(spring.profiles.active),向配置服务器请求获取配置数据。
- 配置服务器根绝客户端的请求参数、以及配置文件中锁配置的标签(spring.cloud.config.label),从git仓库中按照上述规则去查找服务的配置文件。
- 配置服务器将匹配到的git仓库拉取到本地,并建立本地缓存。
- 配置服务器根据拉取到的配置文件创建Spring的ApplicationContext实例,然后将该配置信息返回给客户端。
- 客户端获取到配置服务器返回的数据后,将这些配置数据加载到自己的上下文中。同时,因为这些配置数据的优先级高于本地JAR包中的配置,因为将不再加载本地的配置。
2、集成Git仓库
通过spring.cloud.config.server.git.uri属性设置好git地址,设置好git的用户名和密码。
3、搜索目录
如果配置文件直接放在git根目录下,则不需要进行设置。如果放到特定的子目录下,需要设置searchPath指定目录。
4、本地缓存
配置服务器从git获取配置信息后,将会在本地存储一份。但无法访问到git时,则会读取之前缓存在本地文件系统中的配置,将这些配置信息返回给客户端。
配置的加密与解密
1、安装JCE(Java Cryptography Extension)
Spring Cloud Config所提供的加解密依赖JCE是一组包,提供用于加密、秘钥生成算法和协议,以及消息认证码的算法及实现,这些包实现对称、非对称、块和流密码的加密支持。
- https://www.oracle.com/java/technologies/javase-jce8-downloads.html,下载JCE扩展包jce_policy-8.zip。
- 解压,获得两个jar包:local_policy.jar和US_export_policy.jar。
- 打开$JAVA_HOME/jre/lib/security目录,将该目录下的local_policy.jar和US_export_policy.jar文件备份到其他目录
- 将下载解压后的local_policy.jar和US_export_policy.jar复制过来。
2、使用对称加密
配置服务端:
3、加密/解密端点
- /encrypt:加密端点。使用该端点可以对所提供的字符串进行加密。
- /decrypt:解密端点。使用该端点可以对所要解密的字符串进行解密。
4、客户端解密
- 需要禁用掉配置服务端的解密处理。是否启用配置服务器的解密处理通过spring.cloud.config.server.encrypt.enabled属性控制。
- 在客户端项目,增加和服务器同样的秘钥。encrypt.key=test
- 为客户端增加spring-security-rsa依赖。
5、非对称加密
需要使用Java工具——Keytool。Keytool是一个Java数据证书的管理工具,Keytool使用keystore文件存储秘钥和证书。
keystore文件里包含两种数据:一种是秘钥实体-秘钥或者是私钥和配对公钥(采用非对称加密);另一种是可信任的证书实体,仅包含公钥。
需要使用Keytool生成一个秘钥对。
keytool -genkeypair -alias alias -keyalg RSA -dname “CN=test” -keypass secret -keystore server.jks -storepass password
然后将生成的server.jks文件复制到配置服务器的resources目录下。
修改配置文件
配置服务器访问安全
使用Spring Security来做访问安全控制。
配置服务器:
增加依赖项
配置服务器的高可用
1、整合Eureka
改造配置服务
增加依赖
配置文件中配置服务名称,及Eureka服务器地址
修改启动类,增加@EnableDiscoveryClient注解
改造商品服务器
验证
2、快速失败与响应
默认情况下,只有当客户端向配置服务发起请求时,配置服务器才会从配置仓库中加载配置文件。可以通过设置clone-on-start,让配置服务器在启动时就加载配置文件。
一方面在启动时就执行加载可以及时验证配置仓库是否库用;
另一方面当客户端第一次发起请求时可以立即返回配置数据。
在启动一个服务后,当无法连接到配置服务器时能够快速返回失败
配置客户端开启重试机制
需要先开启快速失败配置,然后再配置客户端的依赖中增加spring-retry和spring-boot-starter-aop两个依赖。
3、动态刷新配置
在配置客户端增加依赖
当配置文件提交到git有变更之后,访问配置客户端的refresh地址来更新本地的配置数据。