SpringCloud的配置中心默认使用Git存储,也可以使用其它方式存储,在微服务环境下,需要同时管理N个微服务的配置文件,这就需要一个配置中心集中管理。
配置中心分为2部分,一是server,二是client,下面构建一个基于本地配置文件的server,先创建一个Gradle工程,依赖配置如下:
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Brixton.SR7'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.cloud:spring-cloud-config-server')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
注意:这是Boot是1.x,Cloud是Brixton
配置启动类,打开config-server,如下:
@EnableConfigServer
@SpringBootApplication
public class CloudApplication {
public static void main(String[] args) {
SpringApplication.run(CloudApplication.class, args);
}
}
接着配置application.properties,内容如下:
spring.application.name=config-server
server.port=7001
# 开启本地配置 会搜索resources目录下配置
spring.profiles.active=native
配置native,这样config就会搜索本地resources目录的配置文件。
下面配置资源文件,如名字为didispace
,则对应文件名为didispace.properties
和didispace-{profile}.properties
,如下:
didispace.properties
from=local
didispace-dev.properties
from=local-dev
启动服务,输入http://localhost:7001/didispace/dev可以查看输出信息
{"name":"didispace","profiles":["dev"],"label":null,"version":null,"propertySources":[{"name":"classpath:/didispace-dev.properties","source":{"from":"local-dev"}},{"name":"classpath:/didispace.properties","source":{"from":"local"}}]}
则config-server启动正常,下面可以配置config-client读取配置文件。
同样创建工程,依赖配置文件如下:
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Edgware.SR4'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.cloud:spring-cloud-starter-config')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
下面创建controller,让它在启动时去请求config-server的属性,如下:
@RefreshScope
@RestController
public class TestController {
@Value("${from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
@Value用于获取properties的值。
@RefreshScope可以动态更新实例。
从这里我们并不知道需要获取哪个properties的值,接着看。
接着配置application.properties文件,内容如下:
spring.application.name=didispace
server.port=7002
spring.cloud.config.label=master
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:7001/
其中master
表示主分支,是指git库中的;application.name一定要是didispace
,要与config-server中的配置文件名字对应,看下client输出的日志:
Fetching config from server at: http://localhost:7001/
Located environment: name=didispace, profiles=[dev], label=master, version=null, state=null
上面的配置信息表示读取config-server中的http://localhost:7001/didispace-dev.properties
,将此url放入浏览器则可显示配置文件内容。
在浏览器上输入http://localhost:7002/from
则显示config-server的配置内容,说明config-client获取config-server配置信息成功。
但也可能很不幸,Client服务启不来,提示:Fetching config from server at: http://localhost:8888
其实这是一个配置文件优先级的问题;SpringCloud里面有个“启动上下文”,主要是用于加载远端的配置,也就是加载ConfigServer里面的配置,默认加载顺序为:加载bootstrap.里面的配置 --> 链接configserver,加载远程配置 --> 加载application.里面的配置;总结:这里需要借助于“启动上下文”来处理加载远程配置。
即把application
改为bootstrap
即可。
配置文件远程热更新
我们更新didispace-dev
的内容,重启config-server,输入http://localhost:7001/didispace-dev.properties
查看更新后的配置文件,再次刷新client发现client配置内容并没有改变,在有多个微服务端,我们不希望把每一个都重启,应该怎么办?
需要配置compile('org.springframework.boot:spring-boot-starter-actuator')
,它包含了/refresh
端点实现,该端点将用于实现客户端应用配置信息的重新获取与刷新。
注意:不能在浏览器上调/refresh
,因为它是POST
,可以使用POSTMAN工具;直接调用/refresh
会报错,有安全限制,要在application中加上endpoints.refresh.sensitive = false
。
通过Git访问
只需要去掉native
,cloud默认采用git,所以要加上git配置,否则就会报错,在application中添加git的配置,如下:
# git管理配置
#C:\Users\FF\AppData\Local\Temp\config-repo-4905208803707912772\config
spring.cloud.config.server.git.uri=https://github.com/xxx/lesson/
spring.cloud.config.server.git.searchPaths=config
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
自己可以在github上注册一个账号并上传一些配置文件就可以自己测试了,从git上下载的配置文件是存入了临时目录,如上。
安全性
配置信息是非常敏感的,要注意其安全性,最简单的方式可以使用对称加密。
查看config-server的加密功能如下:
*/encrypt/status 查看加密功能状态
*/key 查看密钥的端点
*/encrypt 对请求的body加密
*/decrypt 对请求的body解密
在浏览器上输入/encrypt/status
,可以得到如下内容:
{"description":"No key was installed for encryption service","status":"NO_KEY"}
表示加密功能并没有打开。
配置密钥
对称加密
在application中配置encrypt.key=didispace
,再次输入/encrypt/status
则显示
{"status":"OK"}
此时可以使用命令curl
测试加解密功能,如下:
$ curl -s localhost:7001/encrypt -d didispace
8efb9a50b58f6b71240eac1a4591a8c22ff9ab96595099d46a65d71dcae53cac
$ curl -s localhost:7001/decrypt -d 8efb9a50b58f6b71240eac1a4591a8c22ff9ab96595099d46a65d71dcae53cac
-s(silent)表示静音模式。
非对称加密
也可以使用非对称加密方式(如RSA密钥对),它具有更高的安全性。
先使用keytool创建一个config-server.keystore密钥库文件,创建步骤参考java之keytool非对称加密和解密,然后在application添加配置,如下:
encrypt.key-store.location=config-server.keystore
encrypt.key-store.alias=config-server
encrypt.key-store.password=111111 密钥库口令
encrypt.key-store.secret=222222 密钥口令
这只是实现了一个简单的config-server与config-client,后面将结合eureka实现高可用的配置中心。
学习交流群:64691032