Spring Cloud系列教程(十):分布式配置中心Spring Cloud Config(Finchley版本)

电玩女神 2023-07-07 08:05 79阅读 0赞

一、前言

在分布式、微服务系统架构中,一个大的项目在进行服务拆分之后,变成了众多个子服务,由于服务的数量居多,每个服务都有自己的一套配置文件,这时候就不像传统的单体架构SSMSSH、以及当下比较流行的SpringBoot快速开发框架,一个项目基本一份配置文件就可以搞定。而在微服务项目架构中,为了方便众多个服务的配置文件统一进行集中管理、实时的动态更新、与项目代码解耦开来,所以需要分布式配置中心组件,在SpringCloud微服务全家桶中,已经有比较成熟的分布式配置中心组件Spring Cloud Config,本篇文章我们就来学习基于Spring Cloud Config构建分布式配置中心。

二、特点

Spring Cloud Config分为config server端和config clientconfig server它支持服务配置文件存放在配置服务的内存中(即本地文件)同时也支持放在远程GitSVN仓库中。 关于config server端和config client端,简要说明如下:

  • config server 用于读取远程GitSVN仓库中的配置文件信息,缓存在JVM内存当中,另外也会持久化一份到本地硬盘上,此存放路径可以自己设置,后面会讲到;
  • config client 用于连接config server端,从config server端读取配置文件的属性信息,读取有两种方式,一种是通过spring.cloud.config.url,另一种是通过service-id 服务名读取。
    在这里插入图片描述

三、Spring Cloud Config可解决的痛点

  • 集中管理配置文件;
  • 不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release;
  • 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置信息;
  • 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置;
  • 将配置信息以REST接口形式暴露
  • 默认实现基于 Git ,可以进行版本管理

四、准备工作

基于上述理论知识的基础之上,搭建config-server:8080、config-client:8081、eureka-server:8888 三个工程,如图所示。
在这里插入图片描述

五. 搭建eureka-server环境

1. pom.xml

  1. <groupId>com.thinkingcao.api</groupId>
  2. <artifactId>springcloud-eureka-server</artifactId>
  3. <version>0.0.1-SNAPSHOT</version>
  4. <name>springcloud-eureka-server</name>
  5. <description>SpringCloud整合Eureka组件搭建微服务注册中心</description>
  6. <!--SpringBoot依赖版本-->
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>2.0.3.RELEASE</version>
  11. <relativePath/>
  12. </parent>
  13. <!--项目编码、jdk版本、SpringCloud版本定义-->
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
  19. </properties>
  20. <!--声明管理SpringCloud版本依赖信息-->
  21. <dependencyManagement>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-dependencies</artifactId>
  26. <version>${ spring-cloud.version}</version>
  27. <type>pom</type>
  28. <scope>import</scope>
  29. </dependency>
  30. </dependencies>
  31. </dependencyManagement>
  32. <!--依赖信息-->
  33. <dependencies>
  34. <!--springcloud整合eureka服务端组件-->
  35. <dependency>
  36. <groupId>org.springframework.cloud</groupId>
  37. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  38. </dependency>
  39. </dependencies>

2. application.yml

  1. #服务端口号
  2. server:
  3. port: 8888
  4. #定义服务名称(服务注册到eureka名称)
  5. spring:
  6. application:
  7. name: app-thinkingcao-eureka
  8. eureka:
  9. instance:
  10. #Eureka注册中心ip地址
  11. hostname: 127.0.0.1
  12. client:
  13. serviceUrl:
  14. #注册地址
  15. defaultZone: http://${ eureka.instance.hostname}:${ server.port}/eureka/
  16. #表示是否需要将自己注册给自己的注册中心,因为自己是注册中心,单机版本时不需要,设置为false(集群的时候需要是为true)
  17. register-with-eureka: false
  18. #因为自己是注册中心,不需要去检索服务信息,单机版本时不需要,设置为false(集群的时候需要是为true)
  19. fetch-registry: false
  20. #Eureka自我保护机制
  21. server:
  22. #关闭eureka自我保护机制false(默认为true)
  23. enable-self-preservation: false
  24. # 清理间隔(单位毫秒,默认是60*1000)
  25. eviction-interval-timer-in-ms: 2000

3. AppEurekaServer启动类

@EnableEurekaServer: 表示启动eureka server注册中心服务

  1. package com.thinkingcao.api;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  5. @SpringBootApplication
  6. @EnableEurekaServer
  7. public class AppEurekaServer {
  8. public static void main(String[] args) {
  9. SpringApplication.run(AppEurekaServer.class, args);
  10. }
  11. }

六、搭建config-server端

1. 创建项目,选择如下依赖

lombok : 代码简化插件
config server : config server分布式配置中心服务端
Eureka Discovery Client : eureka注册中心客户端依赖,在需要向eureka注册中心注册服务时使用。
在这里插入图片描述

2. 构建远程Git仓库

在这里插入图片描述

3. 创建配置文件

远程仓库:https://gitee.com/Thinkingcao/springcloud-config-repo 是我创建的私有仓库,同时创建一个文件夹叫做config-respo 用来专门存放服务的配置文件,实际项目开发中可以根据项目的服务名字来区分文件夹,config-respo中有个具体的order-dev.yml配置文件,order-dev.yml配置文件内容信息如下:
在这里插入图片描述
注意: 学过SpringBoot的大佬们可能都知道,SpringBoot中配置文件的形式默认是: application-profile.yml或者application-profile.properties,那么在配置中心中也是一样,在Git远程仓库创建配置文件时也是如此,例如: order-dev.yml、order-prod.yml。
其中:

  • profile表示的是环境
  • application表示的是文件名称
  • yml则为文件的类型。

4. config-server依赖

  1. <groupId>com.thinkingcao</groupId>
  2. <artifactId>springcloud-config-server</artifactId>
  3. <version>0.0.1-SNAPSHOT</version>
  4. <name>springcloud-config-server</name>
  5. <description>搭建SpringCloud configServer环境</description>
  6. <!--SpringBoot依赖版本-->
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>2.0.3.RELEASE</version>
  11. <relativePath/>
  12. </parent>
  13. <!--项目编码、jdk版本、SpringCloud版本定义-->
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
  19. </properties>
  20. <!--声明管理SpringCloud版本依赖信息-->
  21. <dependencyManagement>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-dependencies</artifactId>
  26. <version>${ spring-cloud.version}</version>
  27. <type>pom</type>
  28. <scope>import</scope>
  29. </dependency>
  30. </dependencies>
  31. </dependencyManagement>
  32. <!--依赖信息-->
  33. <dependencies>
  34. <!--SpringCloud整合config-server组件-->
  35. <dependency>
  36. <groupId>org.springframework.cloud</groupId>
  37. <artifactId>spring-cloud-config-server</artifactId>
  38. </dependency>
  39. <!--SpringCloud整合-eureka-client组件-->
  40. <dependency>
  41. <groupId>org.springframework.cloud</groupId>
  42. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  43. </dependency>
  44. <!--Lombok简化代码插件-->
  45. <dependency>
  46. <groupId>org.projectlombok</groupId>
  47. <artifactId>lombok</artifactId>
  48. <optional>true</optional>
  49. </dependency>
  50. </dependencies>

5. 配置config-server连接远程git仓库

如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写,本例子是使用私有仓库,所以密码大家在搭环境的时候填写自己Git仓库的账号密码。

  1. #端口号
  2. server:
  3. port: 8080
  4. #定义服务名称(服务注册到eureka名称)
  5. spring:
  6. application:
  7. name: app-config-server
  8. #Spring Cloud Config Server端配置
  9. cloud:
  10. config:
  11. server:
  12. git:
  13. #远程存储库的URI地址。
  14. uri: https://gitee.com/Thinkingcao/springcloud-config-repo
  15. #使用远程Git仓库验证用户名。
  16. username: 617271837@qq.com
  17. #使用远程Git仓库验证密码。
  18. password: xxxxxx
  19. #指定远程Git仓库的分支
  20. default-label: master
  21. #指定本地仓库地址用来存储获取远程Git上的配置文件
  22. basedir: G:\temp\path\config-properties
  23. #git仓库地址下的相对地址,可以配置多个,用,分割,也就是配置文件所在根目录文件夹名称
  24. search-paths: config-respo
  25. #标记以指示启用配置服务器发现(配置服务器URL将通过发现查找)。
  26. discovery:
  27. enabled: true
  28. #在此指定服务注册中心地址,将当前服务注册到eureka注册中心上
  29. eureka:
  30. client:
  31. service-url:
  32. defaultZone: http://127.0.0.1:8888/eureka
  33. #启动注册操作,该值默认为true。若设置为fasle将不会启动注册操作。是否需要去检索寻找服务,默认是true
  34. register-with-eureka: true
  35. #是否需要从eureka上获取注册信息
  36. fetch-registry: true

关于Spring Cloud Config配置文件的属性信息在上面的yml文件中注释已经写的非常的清楚了,这里我就不过多解释。

6. 启动类AppConfigServer

@EnableDiscoveryClient : 开启向注册中心注册服务
@EnableConfigServer : 开启分布式配置中心服务端

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  4. import org.springframework.cloud.config.server.EnableConfigServer;
  5. @SpringBootApplication
  6. @EnableDiscoveryClient
  7. @EnableConfigServer
  8. public class AppConfigServer {
  9. public static void main(String[] args) {
  10. SpringApplication.run(AppConfigServer.class, args);
  11. }
  12. }

7. 测试config-server读取配置文件

启动程序,访问: http://127.0.0.1:8080/order-dev.yaml ,浏览器展示如下结果
在这里插入图片描述
Spring Cloud Config 有一套URL访问规则,我们通过这套规则在浏览器上直接访问即可。
注意: 这里的application指的是Git远程仓库中的配置文件的名字

  1. /{ application}/{ profile}[/{ label}]
  2. /{ application}-{ profile}.yml
  3. /{ label}/{ application}-{ profile}.yml
  4. /{ application}-{ profile}.properties
  5. /{ label}/{ application}-{ profile}.properties

结论: 当访问config-server的程序,格式: Http+IP+Port+远程git仓库的配置文件名称 时,响应结果为整个配置文件的信息,证明配置服务中心可以从远程程序获取配置信息,这时候指定的basedir:G:\temp\path\config-properties本地文件夹,发现配置服务中心将从远程git仓库上的配置文件持久化一份到硬盘中去了,同时也缓存一份到JVM内存中。
在这里插入图片描述

七、如何配置config从本地读取

之前也提到过spring cloud config配置中心支持从本地读取和从远程Git/SVN仓库读取这两种方式,如果想要使用spring cloud config读取本地文件,而不是读取远程Git仓库的配置文件信息,可以通过如下做法实现:

  1. spring:
  2. application:
  3. name: config-server
  4. profiles:
  5. active: native
  6. # 配置中心
  7. cloud:
  8. config:
  9. server:
  10. native:
  11. search-locations: classpath:/config/

在这里插入图片描述
好了,言归正传,我们回到主题上,接下来继续开始搭建config-client端。

八、搭建config-client端

1. 创建项目,选择如下依赖

在这里插入图片描述

2. 依赖信息

  1. <groupId>com.thinkingcao</groupId>
  2. <artifactId>springcloud-config-client</artifactId>
  3. <version>0.0.1-SNAPSHOT</version>
  4. <name>springcloud-config-client</name>
  5. <description>搭建SpringCloud Config端读取Git仓库配置文件信息</description>
  6. <!--SpringBoot依赖版本-->
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>2.0.3.RELEASE</version>
  11. <relativePath/>
  12. </parent>
  13. <!--项目编码、jdk版本、SpringCloud版本定义-->
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  16. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
  19. </properties>
  20. <!--声明管理SpringCloud版本依赖信息-->
  21. <dependencyManagement>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-dependencies</artifactId>
  26. <version>${ spring-cloud.version}</version>
  27. <type>pom</type>
  28. <scope>import</scope>
  29. </dependency>
  30. </dependencies>
  31. </dependencyManagement>
  32. <!--依赖信息-->
  33. <dependencies>
  34. <!-- SpringBoot整合Web组件 -->
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-web</artifactId>
  38. </dependency>
  39. <!--SpringCloud整合config-client组件-->
  40. <dependency>
  41. <groupId>org.springframework.cloud</groupId>
  42. <artifactId>spring-cloud-starter-config</artifactId>
  43. </dependency>
  44. <!--SpringCloud整合-eureka-client组件-->
  45. <dependency>
  46. <groupId>org.springframework.cloud</groupId>
  47. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.springframework.boot</groupId>
  51. <artifactId>spring-boot-starter-actuator</artifactId>
  52. </dependency>
  53. <!--Lombok简化代码插件-->
  54. <dependency>
  55. <groupId>org.projectlombok</groupId>
  56. <artifactId>lombok</artifactId>
  57. <optional>true</optional>
  58. </dependency>
  59. </dependencies>

4. 配置config-client从config-server读取配置信息

坑点1:

客户端的spring.application.name配置config-clent端时要和Git服务器上面的文件名相对应的,如果你的客户端是其他名字就报错找不到参数,config-clent端服务会启动失败。我的Git上面配置文件是 order-dev.yml,所以在配置config-clent端时,spring.application.name必须要为order,我在这里说明一下,大家需要特别注意。

坑点2:

客户端加载到的配置文件的配置项会覆盖本项目已有配置,比如客户端你自己配置的端口是8881,但是如果读取到order-dev.yml这个配置文件中也有配置端口为8882,那么此时客户端访问的地址应该是8882。

  1. #服务端口号
  2. server:
  3. port: 8081
  4. #定义服务名称(服务注册到eureka名称)
  5. spring:
  6. application:
  7. name: order
  8. cloud:
  9. config:
  10. name: ${ spring.application.name}
  11. profile: dev #profile对应config server所获取的配置文件中的{profile}
  12. label: master #指定Git仓库的分支,对应config server所获取的配置文件的{label}
  13. discovery:
  14. #标记以指示启用配置服务器发现(配置服务器URL将通过发现查找)
  15. enabled: true
  16. #读取config-server注册地址
  17. service-id: app-config-server
  18. #uri: http://127.0.0.1:8080/
  19. #在此指定服务注册中心地址,将当前服务注册到eureka注册中心上
  20. eureka:
  21. client:
  22. service-url:
  23. defaultZone: http://127.0.0.1:8888/eureka
  24. #启动注册操作,该值默认为true。若设置为fasle将不会启动注册操作。是否需要去检索寻找服务,默认是true
  25. register-with-eureka: true
  26. #是否需要从eureka上获取注册信息
  27. fetch-registry: true
  28. management:
  29. endpoints:
  30. web:
  31. exposure:
  32. include: "*"

5. 启动类

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. @SpringBootApplication
  4. public class AppConfigClient {
  5. public static void main(String[] args) {
  6. SpringApplication.run(AppConfigClient.class, args);
  7. }
  8. }

6. ConfigClient接口读取值

  1. package com.thinkingcao.api;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.cloud.context.config.annotation.RefreshScope;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. /** * @desc: * @author: cao_wencao * @date: 2020-06-19 13:29 */
  7. @RefreshScope
  8. @RestController
  9. public class ConfigClientController {
  10. //@Value("${port:没找到配置值,读默认值为80吧}")
  11. @Value("${blog.url:没找到配置值,读默认值为www.baidu.com吧}")
  12. private String url;
  13. @RequestMapping("/message")
  14. String getMessage() {
  15. return this.url;
  16. }
  17. }

7. 测试config-client端获取配置文件值

访问URL: http://127.0.0.1:8081/message ,浏览器响应结果如下:

https://thinkingcao.blog.csdn.net/

九、调用actuator/refresh接口更新config-client端值

  • 浏览器发送一个post请求,http://127.0.0.1:8081/actuator/refresh

当Git远程仓库的配置文件内容发生改变的时候,config-server会同步更新最新的文件内容缓存到JVM内存中,同时也会更新持久化到硬盘上的那份文件的内容,但是有一个问题,就是config-client端无法动态感知到config-server服务JVM内存中内容的变化,为此,Spring Cloud Config提供了一个接口来刷新,通过调用/actuator/refresh接口+@RefreshScope注解, 来刷新config-client客户端JVM中的值。使其不需要重启服务即可发生改变。

这种操作看起来是可以解决问题,但是太过于繁琐,在分布式项目开发中,仍旧没有达到动态刷新的效果,但是Spring Cloud Config Bus消息总线为广大分布式开发者解决了这个问题,通过Spring Cloud Config Bus消息总线来实现动态刷新,无需人工干预。
在这里插入图片描述

十、源码

源码: https://github.com/Thinkingcao/SpringCloudLearning/tree/master/springcloud-config

发表评论

表情:
评论列表 (有 0 条评论,79人围观)

还没有评论,来说两句吧...

相关阅读