在使用Spring Boot的时候,我们往往会在application.properties配置文件中写一些值,供应用使用,这样做的好处是可以在代码中引用这些值,当这些值需要作出修改的时候,可以直接修改配置文件就重启生效了(如果你部署的是war格式)。但是在Spring Cloud这种大量微服务的架构中,这么做很容易出错,增加了运维的成本。
本篇要介绍的配置中心就是要把所有微服务需要使用的配置值放在同一个地方统一管理,可以分为不同的版本,不同的环境,当要修改某个配置值时,不管是哪个服务,都可以在同一个地方做出修改。
一、架构简介
Spring Cloud配置中心的架构大致如下:
repo可以是本地,可以是git仓库,可以是svn仓库,配置中心分为服务端和客户端,服务端从仓库中读取配置,客户端从服务端请求配置。
但是这种方法有两个问题,一是服务端只有一个,出问题了那么所有的客户端都用不了;二是假如服务端的地址变了,客户端还要跟着变,比较麻烦。在本系列一开始,我们就介绍了注册中心,这个时候,我们就可以把配置中心的服务端和客户端都注册到注册中心,在构架服务端的集群的时候,只需要直接添加多个节点就可以了,而客户端不再是直接去服务端请求配置,而是向注册中心请求。架构如下:
二、创建配置中心仓库
先在github或者别的git仓库(比如码云、私服等)创建一个仓库config-repo,然后在仓库创建一个目录config-client,接着在目录下创建一个client-config-dev.properties文件,在文件中添加foo=bar,下面的步骤我们会从这个文件中读取foo的值。如果是把仓库clone到本地再做修改的话,记得把内容push到github。
三、创建配置中心服务端
仍然在之前的项目上添加新的功能。新建一个module,名称为config-server,添加Eureka Discovery Client和Config Server两个依赖,如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在启动类加上@EnableEurekaClient和@EnableConfigServer注解
在application.properties中添加以下配置
server.port=8000
spring.application.name=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.cloud.config.server.git.uri=https://github.com/spareyaya/config-server
spring.cloud.config.server.git.search-paths=config-client
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
spring.cloud.config.server.git.uri属性指定的就是git仓库的地址,spring.cloud.config.server.git.search-paths属性是该仓库下的相对路径,这个可以方便我们对不同的微服务做配置文件隔离管理,如果仓库是public的,username和password不用填,private的需要。
四、测试服务端
启动注册中心和config-server,访问http://localhost:8000/client-config-dev.properties,返回了
foo: bar
说明config-server确实是加载了远程仓库的配置文件。事实上,config-server已经把配置文件的内容转换为web的形式了:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
比如我们创建的client-config-dev.properties,application就是client-config,profile是dev,label是仓库的分支名,默认是master分支。
因此我们也可以通过访问http://localhost:8000/client-confi/dev来获取配置的值。
这时候我们在仓库的client-config-dev.properties中添加一个配置(如果是在本地仓库添加记得push到github)
foo1=bar1
不要重启,再次访问http://localhost:8000/client-config-dev.properties,结果返回
foo: bar
foo1: bar1
说明config-server会自动读取最新的内容。
五、创建配置中心客户端
5.1、新建客户端module
本来可以在之前消费者或者提供者服务上添加配置中心客户端的功能的,但是这里不准备这么做了,我们新建一个module,名称为config-client,选择Spring Web、Eureka Discovery Client和Config Client三个依赖,如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
5.2、修改配置
在启动类添加@EnableEurekaClient注解开启注册发现
在application.properties中添加以下配置
server.port=8001
spring.application.name=config-client
另外在resources目录下新建一个bootstrap.properties,加入以下配置
spring.cloud.config.name=client-config
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
解释一下这几个配置的含义:
- spring.cloud.config.name:配置文件application的名称,比如这里是client-config
- spring.cloud.config.profile:运行环境
- spring.cloud.config.label:仓库分支
- spring.cloud.config.discovery.enabled:开启config服务发现
- spring.cloud.config.discovery.service-id:config服务的id,就是config-server中spring.application.name的值
- eureka.client.serviceUrl.defaultZone:注册中心地址
5.3、创建测试的Controller
为了方便测试新建一个Controller如下
@RestController
public class ConfigClientController {
@Value("${foo}")
private String foo;
@RequestMapping("/getFoo")
public String getFoo() {
return foo;
}
}
5.4、测试
启动config-client,访问http://localhost:8001/getFoo
这时我们把远程仓库的foo值给改为barrrrr,然后再重新访问http://localhost:8001/getFoo,发现结果还是bar,这时再次访问http://localhost:8000/client-config-dev.properties却发现foo的值已经是barrrrr了。这是因为我们的客户端是在启动服务的时候就会把配置值读取好,如果远程配置值变了,客户端需要重启才能生效。这么看来,配置中心好像也没多大作用嘛,当然不是,Spring Cloud已经提供了某些机制来刷新配置了,这个下一篇再介绍。
六、总结
配置中心就介绍到这里,下一篇介绍消息总线。
源码已经上传到github:https://github.com/spareyaya/spring-cloud-demo/tree/master/chapter6