SpringCloud之Config天山折梅手

611 阅读9分钟

一、简介

  • 配置中心是微服务架构中一个重要的组件,主要用来专门统一管理各环境的配置信息,Spring Cloud Config 为分布式系统中的外部化配置提供服务器端和客户端支持。当我们的应用从开发到测试再进入生产时,我们呢可以通过修改配置来切换各个环境。

二、文档说明

  • 该文档需要搭建一个eureka注册中心,源码中bike-business是作为客户端使用的,即客户端的配置都在bike-business项目里
  • 关于配置文件的代码,其中只包含了注册中心相关的配置,如果查看完整的配置,请查看源码
  • 该项目采用的是springboot2.4.X其中有些地方的配置与低版本会有不一样的地方,注意boot版本即可

二、配置服务端Config Server

  • pom文件

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
  • 创建git仓库

    1、在git上创建存储配置文件的仓库

    2、也可以指定本地文件的地址进行测试

  • 配置文件

    spring:
      application:
        name: bike-config
      cloud:
        config:
          server:
            git:
              #uri只能到仓库名
              uri: https://gitee.com/bike-project/bike-repo
              #配置多个仓库,如果该配置下没有匹配到对应的配置文件,那么会通过同级的git.uri地址匹配配置文件
              repos:
                #应用名:即业务系统的spring.application.name值
                bike-business:
                  #仓库地址
                  uri: https://gitee.com/bike-project/bike-business
                  #配置文件存储目录可使用通配符规则是:[目录]/[环境](即spring.profile.avctive的值)
                  #这是一个list,可配置多个
                  pattern:
                  - bike-business/sit*
                  - bike-business/prod*
                bike-business2:
                  uri: https://gitee.com/bike-project/bike-business2
                  pattern:
                    - bike-business2/sit*
                    - bike-business2/prod*
              #设置fals来禁用ssl验证,默认为true
              skipSslValidation: true
              username: username
              password: password
              #多层目录search-paths 就从根目录开始写起
              search-paths: bike-business
              #分支设置
              default-label: master
              #超时设置
              timeout: 5
              #如果本地副本变脏,可设置此参数强制从远程更新
              force-pull: true
              #在启动服务时识别错误的配置(比如无效的数据库url),如果为false则可能不会报错,知道其他应用请求时才会识别错误
              clone-on-start: true
              #服务启动时会将远程分支clone的本地库,如果远程分支删除,那么本地分支还是可用状态,一直到下次重启,这时候我们可以设置
              #这个参数为true,默认时false,从本地存储库中强制删除未跟踪的分支
              delete-untracked-branches: true
              #刷新率属性单位为秒,默认为0,这意味着配置服务器将在每次请求时从 Git 存储库中获取更新的配置
              refresh-rate: 4
      #配置用户名和密码来读取配置
      security:
        user:
          name: user
          password: password
    
  • 启动类

    添加@EnableConfigServer注解即可

    @SpringBootApplication
    @EnableConfigServer
    public class BikeConfigApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BikeConfigApplication.class, args);
        }
    
    }
    
  • 验证

    启动项目,访问http://Ip:port/application-dev.yml如果能查看到git仓库配置文件的信息服务器配置成功

  • 总结

    1. 服务启动时,会从git仓库clone到一个本地仓库,我们获取的都是本地仓库的数据

    2. 我们可配置刷新速率来保证获取最新的配置,后面还有消息总线,自动刷新等策略

    3. 对于配置中心,我们习惯性把客户端的引导配置文件起名为bootstrap.yml而不是原来的application.yml,加载配置的优先级是不一样的,bootstrap.yml加载优先级更高,对于仓库的配置文件名称一般还是使用原来的application.yml,他也有多种命名规则,加载优先级也不一样,平时用的不多,这里就不多做分析了。

    4. 如果boot2.4.X以上版本使用bootstrap.yml,需要引入包

      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-bootstrap</artifactId>
      </dependency>
      

三、配置客户端 Client Server

  • pom配置

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
  • 配置文件

    1. bootstrap.yml 作为启动引导文件

      server:
        port: 8122
      spring:
        profiles:
          active: dev
      
    2. bootstrap-dev.yml

      spring:
        application:
          name: bike-business
        cloud:
          config:
            #如果服务端配置了用户名密码,那这里也需要设置
            uri: http://user:password@127.0.0.1:8127
            discovery:
              service-id: bike-config
              enabled: true
            profile: dev
            #读取超时设置
            request-read-timeout: 5000
            #连接超时时间
            request-connect-timeout: 50000
            #如果连接不到配置服务器,想快速异常停止,可配置为true,默认为false
            fail-fast: true
            # 重试机制,配置重试首先需要配置上面的fail-fast:true
            # 如果要完全控制重试,请使用id“configServerRetryInterceptor”添加RetryOperationsInterceptor类型的@Bean。Spring Retry有一个RetryInterceptorBuilder,可以轻松创建一个
            retry:
              #第一次与第二次时间间隔
              initial-interval: 1000
              #最大间隔
              max-interval: 1500
              #等待最大值
              max-attempts: 10000
              #上一次尝试时间间隔的乘数
              multiplier: 2
      
      ##Config Client 提供了一个 Spring Boot Health Indicator,它尝试从 Config Server 加载配置。可以通过设置禁用健康指示器health.config.enabled=false。出于性能原因,响应也被缓存。默认缓存生存时间为 5 分钟。要更改该值,请设置该health.config.time-to-live属性(以毫秒为单位)
      #health:
      #  config:
      #    time-to-live:
      
    3. 实例代码

      /**
       * @author :Nickels
       * @date :2021/4/26
       * @desc :
       */
      @RestController
      @RequestMapping("/bike-business")
      public class BusinessController {
      
          @Value("${server.port}")
          String port;
      
          @Value("${env}")
          String env;
      
          @GetMapping("/hello")
          public String helloBusiness(){
              System.out.println("hello business port : 8122 .....");
              return "hello business port : 8122 .....";
          }
      
          @GetMapping("/env")
          public String env(){
              return port + " : " + env + " : ";
          }
      
      }
      
    4. 验证

      启动项目,访问接口,能够获取远程服务器的配置参数即可成功

    5. 总结

      1. 目前设置了用户名和密码但是好像没生效,需要进一步研究。

      2. 如果boot2.4.X以上版本使用bootstrap.yml,需要引入包

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        

四、消息总线bus

  • 介绍

    Spring Cloud Bus 将分布式系统的节点与轻量级消息代理连接起来。Spring Cloud Config 负责从Git服务器clone配置提供给其他应用,Spring Cloud Bus可以使用此代理来广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,总线就像一个用于横向扩展的 Spring Boot 应用程序的分布式执行器。但是,它也可以用作应用程序之间的通信渠道。该项目为 AMQP 代理或 Kafka 提供启动器作为传输。

  • 架构机制

    1. 自动刷新使用了github的webhooks配置,配置好url和事件,当我们触发事件时,会触发url地址的post调用

      image-20210615150735010.png

    2. 客户端刷新

      img

      通过上图可以看出bus的刷新机制

      • 提交代码触发post给客户端A发送bus/refresh
      • 客户端A接收到请求从Server端更新配置并且发送给Spring Cloud Bus
      • Spring Cloud bus接到消息并通知给其它客户端
      • 其它客户端接收到通知,请求Server端获取最新配置
      • 全部客户端均获取到最新的配置

      这种方式破坏了微服务的职责单一原则和服务节点的对称性,业务系统更多的只是关注自身业务,不应该由某一业务系统再去承担刷新配置的功能。所以我们在此基础上,可选择第二种方式,有配置服务器来承担刷新配置功能。

    3. 服务端刷新

      img

      通过上图看出bus的刷新机制由客户端转为了服务端

      • 提交代码触发post给Server端发送bus/refresh

      • Server端接收到请求并发送给Spring Cloud Bus

      • Spring Cloud bus接到消息并通知给其它客户端

      • 其它客户端接收到通知,请求Server端获取最新配置

      • 全部客户端均获取到最新的配置

  • 配置改动

    1. 服务端改动
      • 添加依赖

        <!--    消息总线    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        
      • 配置文件

        spring:
          application:
            name: bike-config
          cloud:
            config:
              server:
                git:
                  #uri只能到仓库名
                  uri: https://gitee.com/bike-project/bike-repo
                  username: ******
                  password: ******
                  #多层目录search-paths 就从根目录开始写起
                  search-paths: bike-business
                  #分支
                  default-label: master
                  #r如果本地副本变脏,可设置此参数强制从远程更新
                  force-pull: true
              #用于开启开启/关闭 AckRemoteApplicationEvent 事件的发送。
              ack:
                enabled: true
              #用于开启/关闭全局刷新的 Listener
              refresh:
                enabled: true
              #用于开启/关闭消息记录 Trace 的 Listener
              trace:
                enabled: true
              #用于开启/关闭配置新增/修改的 Endpoint
              env:
                enabled: true
        
          #配置用户名和密码来读取配置
          security:
            user:
              name: admin
              password: admin123
        #bus启用的是RabbitMQ 或 Kafka两种代理,我们选择的是RabbitMQ,所以要添加RabbitMQ配置
          rabbitmq:
            host: server-host
            port: 5672
            username: ****
            password: ****
        
        
        management:
          endpoints:
            web:
              exposure:
                include: '*'
          endpoint:
            busrefresh:
              enabled: true
        
    2. 客户端改动
      • 添加依赖

        <!--    消息总线    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        
      • 配置文件

        spring:
          cloud:
            config:
              #如果服务端配置了用户名密码,那这里也需要设置
              uri: http://admin:admin123@127.0.0.1:8127
              discovery:
                service-id: bike-config
                enabled: true
              profile: sit
              #读取超时设置
              request-read-timeout: 5000
              #连接超时时间
              request-connect-timeout: 50000
              #如果连接不到配置服务器,想快速异常停止,可配置为true,默认为false
              fail-fast: true
              # 重试机制,配置重试首先需要配置上面的fail-fast:true
              # 如果要完全控制重试,请使用id“configServerRetryInterceptor”添加RetryOperationsInterceptor类型的@Bean。Spring Retry有一个RetryInterceptorBuilder,可以轻松创建一个
              retry:
                #第一次与第二次时间间隔
                initial-interval: 1000
                #最大间隔
                max-interval: 1500
                #等待最大值
                max-attempts: 10000
                #上一次尝试时间间隔的乘数
                multiplier: 2
        #客户端也需要添加mq配置来消费消息
          rabbitmq:
            host: server-host
            port: 5672
            username: ****
            password: ****
        
    3. Controller修改

      只需要在引用配置文件参数的类上添加@RefreshScope注解

      @RestController
      @RequestMapping("/bike-business")
      @RefreshScope//添加注解
      public class BusinessController {
      
          @Value("${server.port}")
          String port;
      
          @Value("${env}")
          String env;
      
          @GetMapping("/hello")
          public String helloBusiness(){
              System.out.println("hello business port : 8125.....");
              return "hello business port : 8125 .....";
          }
      
          @GetMapping("/env")
          public String env(){
              return port + " : " + env;
          }
      }
      
  • 测试验证

    1. 依次启动bike-config(配置服务器),bike-business(客户端1),bike-business2(客户端2)

    2. 观察mq管理界面注册队列,默认的是topic交换机,注册了三个队列说明配置已经生效成功

    image-20210615153213525.png

    image-20210615153257975.png

    1. 修改码云配置文件参数env

    2. 通过postman模拟执行刷新配置接口,执行post请求

    3. 如果对于多个节点部署,只需要更新部分节点的参数可执行下面的post请求

    4. 请求不同的业务系统接口,观察获取的配置信息是否修改即可

官方地址:Spring Cloud Config

中文地址:中文地址

官方地址:Spring Cloud Bus

中文地址:中文地址

源码地址:源码