[关闭]
@coldxiangyu 2017-06-12T07:53:48.000000Z 字数 5955 阅读 3917

Spring Cloud(三、Config Server 统一配置管理)

WEB框架


微服务架构一般由单一服务进行细粒度拆分,使得微服务数量众多,而且每个服务都要单独配置,所以一套集中式的、动态配置管理必不可少。Spring Cloud提供了Config Server,功能如下:

Config Server的架构图如下:
image_1bi5apavisro1ihb1lc7c716uo9.png-129.7kB
工作流程如下:

  1. 配置中心感知到配置变化(如,git仓库发生commit提交),向Bus投递消息
  2. Bus向服务广播消息
  3. 服务收到消息后,主动向配置中心拉取新配置并应用

其中配置中心可集群部署实现高可用。

接下来我们来配置一个Config Server:
新建config-server模块,pom配置如下:

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>1.5.3.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <properties>
  8. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  9. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  10. <java.version>1.8</java.version>
  11. <spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
  12. </properties>
  13. <dependencies>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-config-server</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-test</artifactId>
  21. <scope>test</scope>
  22. </dependency>
  23. </dependencies>
  24. <dependencyManagement>
  25. <dependencies>
  26. <dependency>
  27. <groupId>org.springframework.cloud</groupId>
  28. <artifactId>spring-cloud-dependencies</artifactId>
  29. <version>${spring-cloud.version}</version>
  30. <type>pom</type>
  31. <scope>import</scope>
  32. </dependency>
  33. </dependencies>
  34. </dependencyManagement>

配置application.properties:

  1. spring.application.name=config-server
  2. server.port=7001
  3. # git管理配置
  4. spring.cloud.config.server.git.uri=https://github.com/coldxiangyu/spring-cloud-demo/
  5. spring.cloud.config.server.git.searchPaths=config-repository
  6. spring.cloud.config.server.git.username=username
  7. spring.cloud.config.server.git.password=password

当然,Config server也支持本地文件存储的配置形式,如下:

  1. spring.profiles.active=native
  2. spring.cloud.config.server.native.searchLocations=file:D:/

不过还是推荐git的形式进行版本控制。

最后创建Spring Boot的程序主类,并添加@EnableConfigServer注解,开启Config Server

  1. @EnableConfigServer
  2. @SpringBootApplication
  3. public class Application {
  4. public static void main(String[] args) {
  5. new SpringApplicationBuilder(Application.class).web(true).run(args);
  6. }
  7. }

接下来我们需要验证一下刚刚建立起来的Config Server能否供外部访问,我们在我们的git工程上再创建一层目录config-repository,专门存储相关配置文件。
上传下面四个文件,分别存储不同环境的配置。

  1. coldxiangyu.properties
  2. coldxiangyu-dev.properties
  3. coldxiangyu-test.properties
  4. coldxiangyu-prod.properties

存储内容分别如下,设置from属性,便于我们稍后客户端进行读取:

  1. from=git-default-1.0
  2. from=git-dev-1.0
  3. from=git-test-1.0
  4. from=git-prod-1.0

然后我们创建一个新的test分支,将1.0版本更新为2.0.
到这里,我们启动我们的Config Server,尝试在浏览器或者POSTMAN进行访问。

URL与配置文件的映射关系如下:

上面的url会映射{application}-{profile}.properties对应的配置文件,{label}对应git上不同的分支,默认为master。
下面我们来访问:http://localhost:7001/coldxiangyu/dev/test
访问json结果如下:

  1. {
  2. "name": "coldxiangyu",
  3. "profiles": [
  4. "dev"
  5. ],
  6. "label": "test",
  7. "version": null,
  8. "state": null,
  9. "propertySources": [
  10. {
  11. "name": "https://github.com/coldxiangyu/spring-cloud-demo/config-repository/coldxiangyu-dev.properties",
  12. "source": {
  13. "from": "git-dev-2.0"
  14. }
  15. },
  16. {
  17. "name": "https://github.com/coldxiangyu/spring-cloud-demo/config-repository/coldxiangyu.properties",
  18. "source": {
  19. "from": "git-default-2.0"
  20. }
  21. }
  22. ]
  23. }

浏览器可以访问之后,我们来尝试在实际的微服务端是如何在Config Server中心拉取配置的。
创建config-client模块,pom配置如下:

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>1.3.5.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <dependencies>
  8. <dependency>
  9. <groupId>org.springframework.cloud</groupId>
  10. <artifactId>spring-cloud-starter-config</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-web</artifactId>
  15. </dependency>
  16. <!-- Allow for automatic restarts when classpath contents change. -->
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-devtools</artifactId>
  20. <optional>true</optional>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-actuator</artifactId>
  25. </dependency>
  26. </dependencies>
  27. <dependencyManagement>
  28. <dependencies>
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-starter-parent</artifactId>
  32. <version>Brixton.SR4</version>
  33. <type>pom</type>
  34. <scope>import</scope>
  35. </dependency>
  36. </dependencies>
  37. </dependencyManagement>

创建bootstrap.properties,指定config server:

  1. #对应application
  2. spring.application.name=coldxiangyu
  3. #对应profile
  4. spring.cloud.config.profile=dev
  5. #对应前配置文件的git分支
  6. spring.cloud.config.label=test
  7. #配置中心的地址
  8. spring.cloud.config.uri=http://localhost:7001/
  9. server.port=7002

这里要注意我们配置的是bootstrap.properties而不是application.properties,因为bootstrap.properties会在应用启动之前读取,而spring.cloud.config.uri会影响应用启动。

接着创建一个REST api获取配置中心from属性:

  1. @RefreshScope
  2. @RestController
  3. class TestController {
  4. @Value("${from}")
  5. private String from;
  6. @RequestMapping("/from")
  7. public String from() {
  8. return this.from;
  9. }
  10. }

通过@Value("${from}")绑定配置服务中配置的from属性。@RefreshScope配置,可以使配置通过/refresh刷新之后,加载新的配置。

我们再创建spring boot启动类:

  1. @EnableDiscoveryClient
  2. @SpringBootApplication
  3. public class Application {
  4. public static void main(String[] args) {
  5. new SpringApplicationBuilder(Application.class).web(true).run(args);
  6. }
  7. }

分别启动config server以及config client,访问:http://localhost:7002/from,如下:
image_1bidio62f1t1l1p5m14uh1q5p14m9.png-6.8kB
可以看到,我们成功获取到了配置中心的配置信息。
我们通过git修改此文件内容为git-dev-3.0,通过访问http://localhost:7001/coldxiangyu/dev/test,我们可以看到,配置中心已经发生了变化。
image_1bidj149r4v31m2sqreu69g2qm.png-15.7kB
再次访问http://localhost:7002/from,发现获取到的信息仍然是2.0版本。这时候我们需要向客户端发送一个POST请求:http://localhost:7002/refresh
image_1bidj5mg1iua1uf6180rsiq1qln13.png-19.7kB
返回了405的错误信息,具体原因我还没来得及研究,我们换一种姿势进行POST请求,浏览器请求可能会有问题,我们改用curl -d {} http://localhost:7002/refresh命令进行refresh:
image_1bidj89671ilh19mq1iusd6tn8b1g.png-11.7kB
这时候再访问http://localhost:7002/from
image_1bidjcet0fj0cqi1k6ium71ar31t.png-9kB
我们在未启动客户端服务的情况下,成功刷新。
不过在应用级的项目中,这样肯定还是过于麻烦的,可以通过Spring Cloud Bus来实现以消息总线的方式通知配置信息的变化,实现自动化更新,也就是我们最上面贴的config Server架构说明。这种方式暂时超出了我们本篇文章的研究范围,后续研究。

本文源码已上传github:https://github.com/coldxiangyu/spring-cloud-demo

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注