Spring Cloud(七):配置中心(Git 版与动态刷新)【Finchley 版】

 发表于 2018-04-19 |  更新于 2018-04-24 | 

Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密 / 解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config 实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于 Spring 构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于 Spring Cloud Config 实现的配置中心默认采用 Git 来存储配置信息,所以使用 Spring Cloud Config 构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过 Git 客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:SVN 仓库、本地化文件系统。

在本文中,我们将学习如何构建一个基于 Git 存储的分布式配置中心,并对客户端进行改造,并让其能够从配置中心获取配置信息并绑定到代码中的整个过程。最后,我们还将了解如何能让客户端获取到修改后的最新配置。

准备工作

准备一个 Git 仓库,在 Github 上面创建了一个文件夹 config-repo 用来存放配置文件,为了模拟生产环境,我们创建以下三个配置文件:

复制

  1. 1
    2
    3
    4
    5
    6
  1. // 开发环境
    config-client-dev.yml
    // 测试环境
    config-client-test.yml
    // 生产环境
    config-client-prod.yml

每个配置文件中都写一个属性 neo.hello, 属性值分别是 dev/test/prod。下面我们开始配置 Server 端。

Server 端

创建一个基础的 Spring Boot 工程,命名为:config-server-git

添加依赖

只需要在 pom.xml 中 加入 spring-cloud-config-server 即可

复制

  1. 1
    2
    3
    4
  1. <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    </dependency>

配置文件

在 application.yml 中添加配置服务的基本信息以及 Git 仓库的相关信息

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  1. spring:
    application:
    name: config-server
    cloud:
    config:
    server:
    git:
    uri: https://github.com/zhaoyibo/spring-cloud-study # 配置git仓库的地址
    search-paths: config-repo # git仓库地址下的相对地址,可以配置多个,用,分割。
    server:
    port: 12000

Spring Cloud Config 也提供本地存储配置的方式。我们只需要设置属性spring.profiles.active=native,Config Server 会默认从应用的src/main/resource目录下检索配置文件。也可以通过spring.cloud.config.server.native.searchLocations=file:E:/properties/属性来指定配置文件的位置。虽然 Spring Cloud Config 提供了这样的功能,但是为了支持更好的管理内容和版本控制的功能,还是推荐使用 Git 的方式。

如果我们的 Git 仓库需要权限访问,那么可以通过配置下面的两个属性来实现;
spring.cloud.config.server.git.username:访问 Git 仓库的用户名
spring.cloud.config.server.git.password:访问 Git 仓库的用户密码

启动类

启动类添加@EnableConfigServer,激活对配置中心的支持

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
  1. @SpringBootApplication
    @EnableConfigServer
    public class ConfigServerApplication {
  2.  
  3. public static void main(String[] args) {
    SpringApplication.run(ConfigServerApplication.class, args);
    }
    }

到此 Server 端相关配置已经完成。

测试

首先我们先要测试 Server 端是否可以读取到 github 上面的配置信息,直接访问 http://localhost:12000/config-client/dev 返回信息如下:

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  1. {
    "name": "config-client",
    "profiles": [
    "dev"
    ],
    "label": null,
    "version": "4e3ca4b9e2bb96c9a0ba012f6c6e0b6cadc48f3e",
    "state": null,
    "propertySources": [
    {
    "name": "https://github.com/zhaoyibo/spring-cloud-study/config-repo/config-client-dev.yml",
    "source": {
    "info.profile": "dev"
    }
    }
    ]
    }

上述的返回的信息包含了配置文件的位置、版本、配置文件的名称以及配置文件中的具体内容,说明 Server 端已经成功获取了 Git 仓库的配置信息。

如果直接查看配置文件中的配置信息可访问 http://localhost:12000/config-client-dev.yml 返回:

复制

  1. 1
    2
  1. info:
    profile: dev

修改配置文件config-client-dev.yml中配置信息为:dev update, 再次在浏览器访问 http://localhost:12000/config-client-dev.yml 返回:dev update,说明 Server 端会自动读取最新提交的内容。

仓库中的配置文件会被转换成 Web 接口,访问可以参照以下的规则:

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

上面的 URL 会映射{application}-{profile}.yml对应的配置文件,其中{label}对应 Git 上不同的分支,默认为 master。以 config-client-dev.yml 为例子,它的 application 是 config-client,profile 是 dev。

Client 端

在完成了上述验证之后,确定配置服务中心已经正常运作,下面我们尝试如何在微服务应用中获取上述的配置信息。
再创建一个基础的 Spring Boot 应用,命名为 config-client。

添加依赖

在 pom.xml 中添加下述依赖:

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
  1. <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

引入 spring-boot-starter-webflux 是为了方便 Web 测试。Spring WebFlux 是随 Spring 5 推出的响应式 Web 框架,这里不展开说明,如果不了解的话直接用 MVC 就好了。

配置文件

需要配置两个配置文件,application.yml 和 bootstrap.yml,配置分别如下:
application.yml

复制

  1. 1
    2
    3
    4
    5
  1. spring:
    application:
    name: config-git
    server:
    port: 13000

bootstrap.yml

复制

  1. 1
    2
    3
    4
    5
    6
    7
  1. spring:
    cloud:
    config:
    uri: http://localhost:12000 # 配置中心的具体地址,即 config-server
    name: config-client # 对应 {application} 部分
    profile: dev # 对应 {profile} 部分
    label: master # 对应 {label} 部分,即 Git 的分支。如果配置中心使用的是本地存储,则该参数无用

特别注意:上面这些与 Spring Cloud Config 相关的属性必须配置在 bootstrap.yml 中,config 部分内容才能被正确加载。因为 config 的相关配置会先于 application.yml,而 bootstrap.yml 的加载也是先于 application.yml。

启动类

启动类不用修改,只用@SpringBootApplication就行了

复制

  1. 1
    2
    3
    4
    5
    6
    7
  1. @SpringBootApplication
    public class SpringCloudConfigClientApplication {
  2.  
  3. public static void main(String[] args) {
    SpringApplication.run(SpringCloudConfigClientApplication.class, args);
    }
    }

在 Controller 中使用@Value注解来获取 Server 端参数的值

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  1. @RestController
    public class HelloController {
  2.  
  3. @Value("${info.profile:error}")
    private String profile;
  4.  
  5. @GetMapping("/info")
    public Mono<String> hello() {
    return Mono.justOrEmpty(profile);
    }
    }

测试

启动项目后访问 http://localhost:13000/info 返回dev说明已经正确的从 Server 端获取到了参数。到此一个完整的服务端提供配置服务,客户端获取配置参数的例子就完成了。

我们再做一个小实验,手动修改 config-client-dev.yml 中配置信息为:dev update 提交到 Github, 再次在浏览器访问 http://localhost:13000/info 返回:dev,说明获取的信息还是旧的参数,这是为什么呢?

因为 Spring Cloud Config 分服务端和客户端,服务端负责将 Git 中存储的配置文件发布成 REST 接口,客户端可以从服务端 REST 接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置。客户端如何去主动获取新的配置信息呢,Spring Cloud 已经给我们提供了解决方案,每个客户端通过 POST 方法触发各自的 /actuator/refresh

Refresh

仅修改客户端即 config-client 项目,就可以实现 refresh 的功能。

添加依赖

复制

  1. 1
    2
    3
    4
  1. <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

增加了spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/actuator/refresh的功能。

开启更新机制

需要给加载变量的类上面加载@RefreshScope,在客户端执行/actuator/refresh的时候就会更新此类下面的变量值。

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
  1. @RestController
    @RefreshScope
    public class HelloController {
  2.  
  3. @Value("${info.profile:error}")
    private String profile;
  4.  
  5. @GetMapping("/info")
    public Mono<String> hello() {
    return Mono.justOrEmpty(profile);
    }
    }

配置

Spring Boot 1.5.X 以上默认开通了安全认证,所以要在配置文件 application.yml 中添加以下配置以将/actuator/refresh这个 Endpoint 暴露出来

复制

  1. 1
    2
    3
    4
    5
  1. management:
    endpoints:
    web:
    exposure:
    include: refresh

测试

改造完之后,我们重启 config-client,我们以 POST 请求的方式来访问 http://localhost:13000/actuator/refresh 就会更新配置文件至最新版本。

我们再来测试:

  1. 访问 http://localhost:13000/info 返回dev
  2. 我将 Git 上对应配置文件里的值改为dev update
  3. 执行 curl -X POST http://localhost:13000/actuator/refresh,返回["config.client.version","info.profile"]%
  4. 再次访问 http://localhost:13000/info 返回dev update

这就说明客户端已经得到了最新的值,Refresh 是有效的。

不过,每次手动刷新客户端也很麻烦,有没有什么办法只要提交代码就自动调用客户端来更新呢,Github 的 Webhook 是一个办法。

Webhook

Webhook 是当某个事件发生时,通过发送 HTTP POST 请求的方式来通知信息接收方。Webhook 来监测你在 Github.com 上的各种事件,最常见的莫过于 push 事件。如果你设置了一个监测 push 事件的 Webhook,那么每当你的这个项目有了任何提交,这个 Webhook 都会被触发,这时 Github 就会发送一个 HTTP POST 请求到你配置好的地址。

如此一来,你就可以通过这种方式去自动完成一些重复性工作,比如,你可以用 Webhook 来自动触发一些持续集成(CI)工具的运作,比如 Travis CI;又或者是通过 Webhook 去部署你的线上服务器。下图就是 Github 上面的 Webhook 配置。

  • Payload URL :触发后回调的 URL
  • Content type :数据格式,两种一般使用 json
  • Secret :用作给 POST 的 body 加密的字符串。采用 HMAC 算法
  • events :触发的事件列表。
events 事件类型 描述
push 仓库有 push 时触发。默认事件
create 当有分支或标签被创建时触发
delete 当有分支或标签被删除时触发

这样我们就可以利用 hook 的机制去触发客户端的更新,但是当客户端越来越多的时候,hook 机制也不够优雅了,另外每次增加客户端都需要改动 hook 也是不现实的。其实,Spring Cloud 给了我们更好解决方案——Spring Cloud Bus。后续我们将继续学习如何通过 Spring Cloud Bus 来实现以消息总线的方式进行通知配置信息的变化,完成集群上的自动化更新。

相关阅读

Spring Cloud(一):服务治理技术概览
Spring Cloud(二):服务注册与发现 Eureka
Spring Cloud(三):服务提供与调用 Eureka
Spring Cloud(四):服务容错保护 Hystrix
Spring Cloud(五):Hystrix 监控面板
Spring Cloud(六):Hystrix 监控数据聚合 Turbine
Spring Cloud(七):配置中心(Git 版与动态刷新)
Spring Cloud(八):配置中心(服务化与高可用)
Spring Cloud(九):配置中心(消息总线)
Spring Cloud(十):服务网关 Zuul(路由)
Spring Cloud(十一):服务网关 Zuul(过滤器)
Spring Cloud(十二):分布式链路跟踪(Sleuth 与 Zipkin)

示例代码:GitHub

参考

springcloud(六):配置中心 git 示例
springcloud(七):配置中心 svn 示例和 refresh
Spring Cloud 构建微服务架构:分布式配置中心【Dalston 版】

Spring Cloud(七):配置中心(Git 版与动态刷新)【Finchley 版】的更多相关文章

  1. 微服务SpringCloud之Spring Cloud Config配置中心Git

    微服务以单个接口为颗粒度,一个接口可能就是一个项目,如果每个项目都包含一个配置文件,一个系统可能有几十或上百个小项目组成,那配置文件也会有好多,对后续修改维护也是比较麻烦,就和前面的服务注册一样,服务 ...

  2. 跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh

    SpringCloud系列教程 | 第七篇:Spring Cloud Config 配置中心高可用和refresh Springboot: 2.1.6.RELEASE SpringCloud: Gre ...

  3. spring cloud --- config 配置中心 [本地、git获取配置文件]

    spring boot      1.5.9.RELEASE spring cloud    Dalston.SR1 1.前言 spring cloud config 配置中心是什么? 为了统一管理配 ...

  4. 微服务SpringCloud之Spring Cloud Config配置中心服务化

    在前面两篇Spring Cloud Config配置中心的博客中都是需要指定配置服务的地址url:spring.cloud.config.uri,客户端都是直接调用配置中心的server端来获取配置文 ...

  5. SpringCloud学习笔记(7):使用Spring Cloud Config配置中心

    简介 Spring Cloud Config为分布式系统中的外部化配置提供了服务器端和客户端支持,服务器端统一管理所有配置文件,客户端在启动时从服务端获取配置信息.服务器端有多种配置方式,如将配置文件 ...

  6. spring cloud深入学习(七)-----配置中心git示例

    随着线上项目变的日益庞大,每个项目都散落着各种配置文件,如果采用分布式的开发模式,需要的配置文件随着服务增加而不断增多.某一个基础服务信息变更,都会引起一系列的更新和重启,运维苦不堪言也容易出错.配置 ...

  7. 玩转Spring Cloud之配置中心(config server &config client)

     本文内容导航: 一.搭建配置服务中心(config server) 1.1.git方式 1.2.svn方式 1.3.本地文件方式 1.4.解决配置中包含中文内容返回乱码问题 二.搭建配置消费客户端( ...

  8. Spring Cloud之配置中心搭建

    一.配置中心服务端搭建 1)引入相关Maven坐标 <dependency> <groupId>org.springframework.cloud</groupId> ...

  9. Spring Cloud Config 配置中心

    请将远程配置文件的格式写对: 比如使用 *.yml 或者 *.properties yml: testconfig: testvalue properties: testconfig=testvalu ...

  10. Spring Cloud Config配置中心的使用

    一.概述 1. 为什么使用? 1> 配置文件太多,不方便维护 2> 配置文件一般都保存这各种明文显示的密码,无法保证配置内容的安全性,也无法做到按权限分配给个人 3> 更新配置项目需 ...

随机推荐

  1. github commit 报错:error: failed to push some refs to 'https:'错误解决方法

    为什么会出现这个问题呢? 因为我在github中删除了一个文件readme.txt,但是本地并不知道我删除了readme.txt,本地中还保存了readme.txt文件,导致了云端的文件,和本地的文件 ...

  2. [转]解決 IE10 瀏覽器無法使用 ASP.NET 表單驗證登入的問題

    今天凌晨在客戶端上線,當程式佈署到正式機後發現我們的網站唯獨只有 IE10 瀏覽器無法成功登入,任何其他瀏覽器版本或使用較低的 IE 版本都可以正常登入,使用 IE 相容性檢視也都可以正常登入,想說會 ...

  3. 多线程CSerialPort类的多串口通信实现

    多线程CSerialPort类的多串口通信实现  工作了之后才发现,之前在学校里真是狭隘封闭.坐井观天,拿之前发表的论文来说,工作后接触到了底层的串口.网口开发,对线程(也叫任务).操作系统时间片轮流 ...

  4. 安装oracle11g时遇到环境不满足最低要求

    在安装oracle11g时出现问题:INS-13001环境不满足最低要求 解决方法:找到下载解压后的文件,依次打开以下文件路径:Oracle11g\database\stage\cvu, 在cvu文件 ...

  5. MySQL必知必会 读书笔记四:数据过滤

    过滤数据 WHERE 只检索所需数据需要指定搜索条件( search criteria) ,搜索条件也称为过滤条件( filtercondition) . 在SELECT语句中,数据根据WHERE子句 ...

  6. jQuery关于复选框的基本小功能

    这里是我初步学习jquery后中巨做的一个关于复选框的小功能: 点击右边选项如果勾上,对应的左边三个小项全部选中,反之全不选, 左边只要有一个没选中,右边大项就取消选中,反之左边全部选中的话,左边大项 ...

  7. webpack新建项目

    记录如何搭建一个最简单的能跑的项目! 1.首先,需要下载安装nodejs环境,可以直接百度搜索nodejs去官网下载符合你操作系统的环境. 安装完nodejs后,在控制台输入命令: npm -vers ...

  8. tornado用户指引(二)------------tornado协程实现原理和使用(一)

    摘要:Tornado建议使用协程来实现异步调用.协程使用python的yield关键字来继续或者暂停执行,而不用编写大量的callback函数来实现.(在linux基于epoll的异步调用中,我们需要 ...

  9. webpack 优化代码 让代码加载速度更快

    一,如何优化webpack构建 (1),缩小文件搜索范围, 优化Loader配置 module.exports = { module: { rules: [ { test:/\.js$/, use:[ ...

  10. php 算法(二分法)只适用于有序表,且限于顺序存储结构

    function demo($array,$low,$high,$k){ if($low<=$high){//判断该数组是否存在 $mid =  intval(($low+$high)/2 ); ...