1.快速入门
默认配置读取
配置源的默认策略是从git获取(由spring.cloud.config.server.git.uri定义URL)
属性串使用JSON格式访问,形式包括以下四种
/ {应用} / {轮廓} [/ {标号}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
- application:取自 定义的spring.config.name
- profile:是定义不同应用环境
例如dev代表开发,test代表测试 beta代表 准生产 - label:默认是master
1.1 客户端开发
需要继承 parent spring-cloud-starter-parent ,依赖于 org.springframework.cloud:spring-cloud-starter-config
主启动类默认读取 spring.cloud.config.uri的属性值来获取外部配置的服务端地址,此属性定义在bootstrap、application中即可(yml、properties均可 一般建议yml) 例如:
spring.cloud.config.uri: http://myconfigserver.com
或
spring.cloud.config.uri: https://github.com/spring-cloud-samples/config-repo
2.服务端开发
必须实现注解 @EnableConfigServer
application.yml配置样例
server:
port : 8888
spring:
cloud:
config
server
git
uri: https://github.com/spring-cloud-samples/config-repo
uri 可以是本地文件 unix格式为 file:// u s e r . h o m e / c o n f i g − r e p o , w i n d o w s 格 式 为 f i l e : / / / {user.home}/config-repo ,windows格式为 file:/// user.home/config−repo,windows格式为file:///{user.home}/config-repo
2.1 环境仓库
spring.profiles.active定义需要加载的配置环境,此时active指定的活动配置文件优先于默认配置文件
如果 active指定有多个配置,那么写在最后的优先级最高(我理解的意思就是,如果属性相同,最后的配置会覆盖之前的配置)
例如 bootstrap.yml定义
spring:
application:
name:foo
profiles:
active:dev,mysql
此时 mysql 配置生效
此参数可作为环境变量或命令行参数在程序启动脚本中定义
如果在 application.yml 定义 application-db.yml的文件引用, application-db.yml文件将会优先加载并使用
模式匹配和多个仓库
application.yml 样例
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
repos:
simple: https://github.com/simple/config-repo
special:
pattern: special*/dev*,*special*/dev*
uri: https://github.com/special/config-repo
local:
pattern: local*
uri: file:/home/configsvc/config-repo
假如 按照 {application}/{profile} 的格式访问 没有匹配到 按照 pattern 定义的匹配串 没有匹配到 simple、special、local
则使用默认uri定义的的配置仓库服务器 https://github.com/spring-cloud-samples/config-repo
simple: https://github.com/simple/config-repo 是简写方式 如果要写其他属性例如 credentials, pattern
则需要按照local、sprcial的格式书写完整
pattern取值
pattern是一个特征匹配串数组 可以写成 “,” 分隔的特征串 或者 "-"分行显示
例如上述的 special 可以写为
special:
pattern:
-- special*/dev*
-- *special*/dev*
第一行意思是 以 special 匹配以 special 开头的包含 /dev 的特征串 第二行意思是 以 special 匹配带
special 的包含 /dev 的特征串
searchPaths:配置文件可以归集在一个目录中 用 searchPaths 指定目录
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
searchPaths: foo,bar*
表示在 foo目录和bar开头的子目录中查找配置文件
searchPaths也支持传参 例如 searchPaths:’{application}’ 则依赖于 application的属性值
cloneOnStart 默认启动配置,
以下例子代表 team-a配置将在应用启动时加载并clone, team-b和team-c不被加载,当有请求时才会被加载
spring:
cloud:
config:
server:
git:
uri: https://git/common/config-repo.git
repos:
team-a:
pattern: team-a-*
cloneOnStart: true
uri: http://git/team-a/config-repo.git
team-b:
pattern: team-b-*
cloneOnStart: false
uri: http://git/team-b/config-repo.git
team-c:
pattern: team-c-*
uri: http://git/team-a/config-repo.git
强行拉取仓库信息 解决 "anyway of the local copy gets dirty"的问题,如果是多个仓库 可以在每个仓库后加例如
spring:
cloud:
config:
server:
git:
uri:https://github.com/spring-cloud-samples/config-repo
force-pull:true
repos:
team-a:
pattern: team-a-*
uri: http://git/team-a/config-repo.git
force-pull: true
team-b:
pattern: team-b-*
uri: http://git/team-b/config-repo.git
认证
git远程需要认证机制 需要使用username和 password属性
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
username: trolley
password: strongpassword
如果git已经默认配置了ssh认证信息 也可以使用 git@github.com:configuration/cloud-configuration
也可以用-Dhttps.proxyHost 和 -Dhttps.proxyPort 在jvm参数设置https代理
AWS CodeCommit 认证:忽略 先不管
配置 Git SSH
激活基于属性的SSH配置,
spring.cloud.config.server.git.ignoreLocalSshSettings 属性设置为true
spring:
cloud:
config:
server:
git:
uri:git @ gitserver.com:team / repo1.git
ignoreLocalSshSettings:true
hostKey:someHostKey
hostKeyAlgorithm:ssh-rsa
privateKey:|
-----开始RSA私钥-----
MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM + o7ds7FRES5RTjv2RT / JVNJCoqF
OL8 + ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq + ObBBNhg5N + hOwKjjpzdj2Ud
1l 7R + wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
fY6yTiKxFzwb38IQP0ojIUWNrq0 + 9 Xt + NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
BO56 / RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD + valhfD75MxoXU7s3FK7yjxy3rsG
EmfA6tHV8 / 4 a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
5 MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
+ AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ / 28 I4BX / mOSe
pZVnfRixAoGBAO6Uiwt40 / PKs53mCEWngslSCsh9oGAaLTf / XdvMns5VmuyyAyKG
ti8Ol5wqBMi4GIUzjbgUvSUt + IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
xrtWZ9eNj2TsIAMp / svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx / AoGBANYW
dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
PhKpeaeIiAaNnFo8m9aoTKr + 7 I6 / uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
FwlJc / xlFqDusrcHL7abW5qq0L4v3R + FrJw3ZYufzLTVcKfdj6GelwJJO + 8 wBm + R
gTKYJItEhT48duLIfTDyIpHGVm9 + I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
VAykcNgyDvtAVODP + 4 m6JvhjAoGBALbtTqErKN47V0 + JJpapLnF0KxGrqeGIjIRV
cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
KTbTjefRFhVUjQqnucAvfGi29f + 9 oE3Ei9f7wA + H35ocF6JvTYUsHNMIO / 3 gZ38N
CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC /围兜
q0TY3we + ERB40U8Z2BvU61QuwaunJ2 + uGadHo58VSVdggqAo0BSkH58innKKt96J
69 pcVH / 4 rmLbXdcmNYGm6iu + MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
----- END RSA私钥-----
属性 | 备注 |
---|---|
ignoreLocalSshSettings | 如果为true,则使用基于属性的SSH配置而不是基于文件 ,配置是 spring.cloud.config.server.git.ignoreLocalSshSettings 而不是仓库 |
privateKey | 有效的SSH私钥。如果ignoreLocalSshSettings为true,则必须设置此属性,并且Git URI是SSH格式 |
hostKey | 有效的SSH主机密钥。和 hostKeyAlgorithm 一起使用 |
hostKeyAlgorithm | 从ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521中选择。和 hostKey 一起使用 |
strictHostKeyChecking | true或false。如果为false,则忽略 hostKey 错误 |
2.1.2 文件系统管理对仓库版本的影响
pull的本地仓库一般以 config-repo- 开头,可能放在临时目录中例如 /tmp/config-repo-
可通过指定
spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir
更改Config Server目录地址 避免被清理
2.1.3 本地版本管理
本地配置文件中指定 spring.profiles.active = native 代表使用本机配置文件启动 Config Server
路径格式
file://${user.home}/config-repo windows file:///${user.home}/config-repo
searchLocations 默认和 Spring Boot应用一致,例如
[classpath:/, classpath:/config, file:./, file:./config]
也可以使用参数 例如 file:/tmp/config,file:/tmp/config/{label}
禁用参数需要指定 spring.cloud.config.server.native.addLabelLocations=false
2.1.4 后台管理工具Vault
Vault 是安全访问机密的工具,例如API密钥,密码,证书等。Vault为任何机密提供统一的界面,同时提供严格的访问控制并记录详细的审计日志。
具体使用略 有兴趣的可以看 https://learn.hashicorp.com/vault/#getting-started
2.1.5共享配置在多应用的共享机制
基于application* (application.properties, application.yml, application-*.properties)格式的配置文件对于 client applications是可见的
这就是讲的配置的私有性和可见性
2.1.6 多环境配置仓库
从git和svn配置仓库获取配置 order代表优先级 数值越小优先级越高
加入没有master 版本则会同步失败,一个库失败则全部失败
spring:
profiles:
active: git, svn
cloud:
config:
server:
svn:
uri: file:///path/to/svn/repo
order: 2
git:
uri: file:///path/to/git/repo
order: 1
自定义多环境配置仓库
实现 EnvironmentRepository 接口创建自定义仓库
Ordered 定义优先级 ,覆盖 getOrdered 方法可以控制优先级,不重写则 自定义的仓库配置优先级最低
2.1.7 属性覆盖 Property Overrides
spring.cloud.config.server.overrides用于覆盖属性 例如
spring:
cloud:
config:
server:
overrides:
foo:bar
所有 spring.cloud.config.server.foo
的值将=bar 替代原来的值
““可转义 ${} 例如 ${app.foo:bar} 将不会解析为 app.foo=bar ,此时需要客户端自定义app.foo的值,因此
除了你需要重写server端的某个属性值时,其他时候不用考虑””
同时,也可以强制客户端覆盖的值 强制恢复为默认值 ,remote repository.使用 spring.cloud.config.overrideNone=true
即可
##2.2 健康指标
运行状况指示器,用于检查配置 EnvironmentRepository是否正常
spring:
cloud:
config:
server:
health:
repositories:
myservice:
label:mylabel
myservice-dev:
name:myservice
profiles:development
禁用健康指标spring.cloud.config.server.health.enabled=false
2.3 安全性
用默认的Spring Boot配置的HTTP Basic安全性,借助 spring-boot-starter-security工具
默认user用户和随机密码(security.user.password),推荐再加密
2.4 加解密
下载 JCE ( “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” from Oracle)
替换 JRE lib/security
下的两个策略文件
{cipher}
开头的加密串 如果不能解析 则删除,并新增其他属性定义为不可用,避免被盗及碰撞
application.yml.
spring:
datasource:
username: dbuser
password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
application.properties。
spring.datasource.username:dbuser
spring.datasource.password:{cipher} FKSAJDFGYOS8F7GLHAKERGFHLSAJ
加解密样例
$ curl localhost:8888/encrypt -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
也可以对 /*/{name}/{profiles} 形式的路径加密
Spring Cloud CLI 下加解密
$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
文件加密(例如,用于加密的RSA公钥),必须在密钥值前加上“@”并提供文件路径,关键参数必须加–前缀 例如
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+..
##2.5 密钥管理
Config Server可以使用对称(共享)密钥或非对称密钥(RSA密钥对)
对称密钥设置encrypt.key或环境变量ENCRYPT_KEY
非对称密钥设置 encrypt.key PEM编码的文本值 ,秘钥存贮在 encrypt.keyStore.* *包含:
- location 资源文件路径
- password 用于(解锁 keystore)
- alias 标识要使用store中的哪个key
加密是使用公钥完成的,并且需要私钥进行解密。
2.6创建用于测试的密钥库
创建秘钥
$ keytool -genkeypair -alias mytestkey -keyalg RSA \
-dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
-keypass changeme -keystore server.jks -storepass letmein
可用把 server.jks 秘钥文件放在classpath里,然后在 Config Server的 application.yml中配置 使用秘钥:
encrypt:
keyStore:
location: classpath:/server.jks
password: letmein
alias: mytestkey
secret: changeme
2.7 使用多个key和自选key
Config Server 查找 {name:value} 为前缀的(Base64编码)密码文本,秘钥传递给 TextEncryptorLocator ,并由其调用TextEncryptor为密码定位 如果已经配置秘钥(encrypt.keystore.location),定位器将在store中查找"key"前缀为别名的
秘钥,例如:
foo:
bar: `{cipher}{key:testkey}...`
定位器将查找名字为 testkey 的key ,或者通过{secret:…}前缀匹配的值提供秘钥,但如果不是,则默认使用密钥库密码。
如果确实 提供了密码,建议您使用自定义加密 SecretLocator
如果要让Config Server处理所有加密和解密,{name:value}前缀也可以添加到发布到/encrypt
2.8提供加密属性
关闭加解密(对the decryption of outgoing properties有效)
spring.cloud.config.server.encrypt.enabled=false
3. 其他可用格式
略
4.提供纯文本
有以下配置文件
application.yml
nginx.conf
nginx.conf:
server {
listen 80;
server_name ${nginx.server.name};
}
application.yml
ginx:
server:
name: example.com
---
spring:
profiles: development
nginx:
server:
name: develop.com
/foo/default/master/nginx.conf 值如下:
server {
listen 80;
server_name example.com;
}
/foo/development/master/nginx.conf 值如下:
server {
listen 80;
server_name develop.com;
}
5. 结合Config Server 做嵌入开发
Config Server可独立运行或者在其他程序运行,此时需要使用 EnableConfigServer 注解
此时 spring.cloud.config.server.bootstrap 可指定从远程存储库配置,默认读取 bootstrap.yml
spring.cloud.config.server.prefix
可订阅URL位置,以 **/**开头 但是不能以 / 结尾,此时Config Server中调用 @RequestMappings
的 server.servletPath或 server.contextPath 使用此属性值
如果只使用本地单节点仓库配置,则不需要使用 @EnableConfigServer ,直接指定 spring.cloud.config.server.bootstrap=true
即可
6.推送通知和Spring Cloud Bus
工程增加 spring-cloud-config-monitor依赖项 并且在Config Server中激活Spring Cloud Bus,则会启用“/monitor”功能
RefreshRemoteApplicationEvent 在 Config Server和 client application 激活spring-cloud-bus之后将会被使用
本地git文件更改也将会被广播
7. Spring Cloud Config客户端
7.1 服务发现
默认情况下 客户端在 bootstrap.yml 里配置 服务器地址spring.cloud.config.uri 即可
如果使用 DiscoveryClient 框架 例如 Spring Cloud Netflix、Eureka Service Discovery或Spring Cloud Consul(Spring Cloud Zookeeper尚不支持)那么可以根据需要将Config Server注册到Discovery Service,但在默认的“Config First”模式下,客户端将无法利用注册。
- bootstrap.yml 配置 spring.cloud.config.discovery.enabled=true 标识用
DiscoveryClient以找到配置服务器 - 如果用 Netflix,则需要定义 Eureka服务器地址
eureka.client.serviceUrl.defaultZone, - 默认服务ID是“configserver” service id 在客户端上是 spring.cloud.config.discovery.serviceId,等同于server端的
spring.application.name
discovery client 都支持数据映射map (Eureka eureka.instance.metadataMap),
例如 客户端 bootstrap.yml.
eureka:
instance:
...
metadataMap:
user: osufhalskjrtl
password: lviuhlszvaorhvlo5847
configPath: /config
7.3配置客户端快速失败 Config Client Fail Fast
配置 bootstrap.yml的spring.cloud.config.failFast=true
属性, 异常时无法连接到配置服务器可以停止此客户端
7.4 配置客户端重试 Config Client Retry
失败后尝试 需要先配置 spring.cloud.config.failFast=true
然后 配置 pring-retry
和 spring-boot-starter-aop
,默认重试6次,首次间隔1000ms毫秒 ,以后乘以1.1 ,依次类推
可参考 spring.cloud.config.retry.* 配置
也可以自定义bean RetryInterceptorBuilder 来控制重试机制
7.5查找远程配置资源
Config Service 默认 /{name}/{profile}/{label} 参数为:
- “name” = ${spring.application.name}
- “profile” =
${spring.profiles.active} (actually Environment.getActiveProfiles()) - “label” = “master”
以上三个参数在 spring.cloud.config.* 可找到并覆盖默认配置
label可用于版本回滚,可"," 分隔 用于查找分支 例如 spring.cloud.config.label=myfeature,develop
7.6安全
bootstrap.yml.
spring:
cloud:
config:
uri: https://user:secret@myconfig.mycompany.com
或者
bootstrap.yml.
spring:
cloud:
config:
uri: https://myconfig.mycompany.com
username: user
password: secret
在Cloud Foundry 部署应用则需要服务认证才能使用,例如需要使用配置仓库 configserver的配置
bootstrap.yml.
spring:
cloud:
config:
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}
7.6.1健康指标
禁用运行状况指示器health.config.enabled=false 一般缓存5分钟
设置缓存属性 health.config.time-to-live属性(以毫秒为单位)
7.6.2提供自定义RestTemplate
CustomConfigServiceBootstrapConfiguration.java.
@Configuration
public class CustomConfigServiceBootstrapConfiguration {
@Bean
public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
ConfigClientProperties clientProperties = configClientProperties();
ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties);
configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
return configServicePropertySourceLocator;
}
}
在resources/META-INF创建一个名为的文件 spring.factories并指定您的自定义配置。
spring.factories.
org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration
7.6.3 Vault
使用Vault 时,设置 token属性提供令牌
bootstrap.yml.
spring:
cloud:
config:
token: YourVaultToken
7.7 Vault
7.7.1 Vault中的嵌套密钥
Vault支持将密钥嵌套在Vault中存储的值中。例如
echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -
上述代码将JSON对象写入Vault
@Value("${appA.secret}")
String name = "World";
上面的代码将name变量设置值为appAsecret .通过 (appA.secret 赋值)