SpringCloud Config 分布式配置中心

一、前言

        接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第七篇,即介绍 Config 分布式配置中心。

二、概述

2.1 目前的问题

        微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。

        通俗一点就是假设一个项目被拆分成了几百个小的子服务,而每个小的子服务又有自己的 application.yml 文件,如果要修改一些公共的东西,那么就需要这几百个小的子服务都进行修改,想想就比较可怕。

        而 SpringCloud 提供了 ConfigServer 来解决这个问题。

2.2 ConfigServer 是什么

        SpringCloud Config 为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。如下图:

        SpringCloud Config 分为服务端和客户端两部分。

        服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。

        客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用 git 来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过 git 客户端工具来方便的管理和访问配置内容。

2.3 ConfigServer 作用

        1、集中管理配置文件

        2、不同环境不同配置,动态化的配置更新,分环境部署比如 dev/test/prod/beta/release

        3、运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息。

        4、当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置。

        5、将配置信息以 REST 接口的形式暴露。

2.4 与 GitHub 整合配置

        由于 SpringCloud Config 默认使用 Git 来存储配置文件(也有其它方式,比如支持 SVN 和本地文件),但最推荐的还是 Git,而且使用的是 http/https 访问的形式。

2.5 官网地址

        官网的地址,在这块

三、Config 服务端配置与测试

3.1 git Hub 相关操作

        首先用你自己的账号在 GitHub 官网上新建一个名为 springcloud-config 的新 Repository,如下图:

        然后在实体库里面创建三个配置文件,分别用来模拟开发环境、测试环境和生产环境,名称和内容如下:

3.2 新建工程

        新建一个 cloud-config-center-3344 模块,将它设置成配置中心模块,pom.xml 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.springcloud</groupId>
        <artifactId>SpringCloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-config-center-3344</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

        application.yml 内容如下所示,需要配置 gitHub 的代码地址和工程名字,以及分支的名称。

server:
  port: 3344

spring:
  application:
    name:  cloud-config-center #注册进Eureka服务器的微服务名
  cloud:
    config:
      server:
        git:
          uri: https://github.com/BuGeiQianJiuZa/springcloud-config.git # GitHub上面的git仓库名字
          ####搜 索目录
          search-paths:
            - springcloud-config
      #### 读取分支
      label: master

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

        主启动类的代码如下所示:

@SpringBootApplication
// 设置为配置中心的注解
@EnableConfigServer
public class ConfigCenterMain3344
{
    public static void main(String[] args) {
        SpringApplication.run(ConfigCenterMain3344.class, args);
    }
}

         在 windows 下修改 hosts 文件,添加一个映射,如下:

3.3 测试

        接下来测试下是否可以通过上面我们新建的微服务获取 GitHub 配置信息,启动 cloud-eureka-server7001 和 cloud-config-center-3344 模块,在浏览器输入:http://config-3344.com:3344/master/config-dev.yml,如下图,可以看到,可以正常读取配置文件的内容

3.4 配置读取规则

        配置读取规则的意思就是可以通过哪种写法来读取配置文件的内容。其中 label 表示分支 branchname 表示服务名,profiles 表示环境 dev/test/prod application 表示配置文件名称。

3.4.1 第一种

        可以采用这种格式 /{label}/{application}-{profile}.yml 来获取内容,如下图:

3.4.2 第二种

        可以采用这种格式 /{application}-{profile}.yml 来获取内容,如下图:

3.5 小结

        成功实现了通过 SpringCloud Config 读取 GitHub 的配置信息。

四、Config 客户端配置与测试

4.1 新建工程

        新建一个 cloud-config-center-3355 模块作为客户端进行测试,pom.xml 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.springcloud</groupId>
        <artifactId>SpringCloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-config-client-3355</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

4.2 bootstrap 配置文件说明

        如果像平常一样,我们需要创建一个 application.yml 的配置文件,但这块我们要创建一个 bootstrap.yml 的配置文件。为什么呢?因为 applicaiton.yml 是用户级的资源配置项, bootstrap.yml 是系统级的,优先级更加高。

        Spring Cloud 会创建一个 Bootstrap Context,作为 Spring 应用的 Application Context 的父上下文。初始化的时候,Bootstrap Context 负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的 Environment

        Bootstrap 属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap context Application Context 有着不同的约定,所以新增了一个 bootstrap.yml 文件,保证 Bootstrap Context Application Context 配置的分离。

        所以要将 Client 模块下的 application.yml 文件改为 bootstrap.yml,这是很关键的,因为 bootstrap.yml 是比 application.yml 先加载的。bootstrap.yml 优先级高于 application.yml

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: master #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称   上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 #配置中心地址k

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

4.3 配置业务类

        主启动类的代码如下所示:

@EnableEurekaClient
@SpringBootApplication
public class ConfigClientMain3355
{
    public static void main(String[] args)
    {
        SpringApplication.run(ConfigClientMain3355.class,args);
    }
}

        业务类的代码如下所示:

package com.springcloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {

    // 获取的是 gitHub 上配置的 config.info 的值
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo()
    {
        return configInfo;
    }
}

4.4 测试

        分别启动 cloud-eureka-server7001cloud-config-center-3344 cloud-config-center-3355 模块,先访问 http://config-3344.com:3344/master/config-dev.yml,进行自测,如下图:

        然后进行客户端测试访问,输入 http://localhost:3355/configInfo ,如下图,可以看到,也可以获取到 gitHub 上的属性值。

4.5 小结

        我们成功实现了客户端 3355 访问 SpringCloud Config3344 通过 GitHub 获取配置信息。

4.6 分布式配置的动态刷新问题

        假设此时 Linux 运维人员修改了 GitHub 上的配置文件内容做调整,比如说把 version 改成了 2,如下图:

        刷新 3344,发现 ConfigServer 配置中心立刻响应,如下图:

        刷新 3355,发现 ConfigClient 客户端没有任何响应,如下图:

        3355 没有变化,除非自己重启或者重新加载才可以读取最新的配置信息,难道每次运维修改配置文件,客户端都需要重启?

五、Config 客户端之动态刷新

5.1 相关配置

        为了避免每次更新配置都要重启客户端微服务 3355,我们研究研究如何让客户端动态的刷新,首先修改 cloud-config-center-3355 模块,在 pom.xml 中引入如下的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

        修改 bootstrap.yml 配置文件,添加暴露监控端点,如下:

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: master #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称   上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 #配置中心地址k

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

# 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

        在业务类 ConfigClientController 中添加 @RefreshScope 注解,如下:

@RestController
@RefreshScope
public class ConfigClientController {

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo()
    {
        return configInfo;
    }
}

        此时启动 cloud-eureka-server7001cloud-config-center-3344 cloud-config-center-3355 模块,启动完成后将 version 的版本改成 3,如下图:

 

        刷新 3344,发现 ConfigServer 配置中心立刻响应,如下图:

        刷新 3355,发现 ConfigClient 客户端仍然没有任何响应,如下图:

5.2 发送 post 请求 

        这是因为还差了一个步骤:需要运维人员发送 Post 请求刷新 3355,即执行 curl -X POST "http://localhost:3355/actuator/refresh" 命令进行刷新,如下:

        执行完该命令后,再次测试 3355,如下图:

        可以看到,成功实现了客户端 3355 刷新到最新配置内容。

5.3 问题思考

        假设现在有几百个微服务的客户端,每个微服务都要执行一次 post 请求,都是需要手动刷新的嘛?能否有一种方式替换这种手动刷新的方式?接下来介绍消息总线来解决这个问题。

  • 41
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值