每次有人提到极简这个词,都会说极简不是偷懒,是一种 balabala ……
我想说: 我,就是要偷懒!
下面介绍可能是最简单的 spring 的配置中心(也许用某个框架的配置中心这种词不太对,先就这样吧)。
这个配置中心依赖两个 spring 的组件: spring-cloud-config
和 spring-cloud-actuator
。
spring-cloud-config
只需两分钟即可搭建一个 spring-cloud-config 的配置中心:
引入 maven 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
通过配置中心自身的配置文件指定一个配置文件(其他服务的配置)存在的路径,以及访问的一些设置,例如
spring:
cloud:
config:
server:
native:
search-locations: classpath:/configurations
profiles:
active: native
security:
user:
password: dev
server:
port: 8888
其中 native.search-locations: classpath:/path 这种方法能用,但是还不够好,可以使用这样的配置:
spring:
application:
name: configuration-center-name
cloud:
config:
server:
git:
uri: https://github.com/Kicey/config-repo
username: Kicey
password: duang
default-label: master # 配置文件分支
search-paths: config # 配置文件所在根目录
没错,可以使用 git 仓库,只需要在配置文件写上相应的配置,其余将自动完场,那么就能利用 git 的版本控制等一系列功能!突出一个懒字。
(注意:请按照 spring-cloud-config 的规范命名配置文件,懒得写了, baidu/google 一下)
添加注解
@EnableConfigServer
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
这是一个普通的 spring 应用的入口,只是多了一个 @EnableConfigServer
的注解。
好了,完成!
好吧,还没有,现在的配置中心能正常提供配置(直接可通过 http 请拿到数据),但是还缺点什么。
还缺配置的更新和使用配置的服务。
服务读取配置
在依赖这个配置中心的应用中
加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
bootstrap.yml 中加入配置
(关于 bootstrap.yml 和 application.yml 请看这篇文章 application.yml与bootstrap.yml的区别 - 简书 (jianshu.com),放心,同样简单)
spring:
application:
name: gateway
cloud:
config:
uri: http://${CONFIG_HOST:localhost}:${CONFIG_PORT:8888}
fail-fast: true
password: ${CONFIG_PASS:dev}
username: user
结束,到此位置配置中心上的配置就能使用了,但是还存在一个问题——配置更新。
在使用 spring-cloud-config 的情况下,从配置中心的读取的配置被当作从本地的 application.yaml 中的配置(这么说有点不妥,但是理解很快,真要说是 spring 对环境变量作了抽象,这两种配置方式在抽象上是等价的)。也就是说,spring 只在启动应用时加载一次配置,之后即使 git 仓库中的配置更新了,它也不会去拉取配置。
spring actuator
spring-cloud-config-server 和读取其配置的服务都没有自动热更新,就是说它们在默认的情况下只在程序启动之后去读一次配置,之后你再改是无效的。
注意:下面的更改均在读取配置的服务中,而不是配置中心!
为了实现配置的热更新,我们需要 actuator。同样简单
首先,加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
再加配置文件内容
management:
endpoints:
web:
exposure:
include: "*"
server:
port: ${PORT:8888}
好了,完成了。
之后 post 服务(非配置中心)的 /actuator/refresh
就会刷新配置。你可能会问,客户端刷新配置能懂,毕竟加入了新的依赖,你服务端咋也刷了?那么,你猜 spring 在设计的时候服务请求刷新配置,然后配置是通过 spring-cloud-config 获取的,那么配置中心得到刷新调用后会不会更新自己的数据?
(也可以在配置中心上使用 actuator 在没有一个服务的配置刷新请求时,也能完成配置中心自己的更新)。
完。
等等,还需要提醒的是注意 @Value
类似的读取配置的注解,只在启动时读取一次,即使之后本地应用中的配置都更新了,要动态的配置请使用其他的方式吧。