spring cloud config + bus 实现配置中心动态刷新配置

2,455 阅读4分钟

重要步骤及其注意点

  • 安装 rabbitmq (具体各环境如何安装请百度或google,这里不做累述)
  • 引入相关依赖(请使用spring boot 2.0 以上的发行版,或与本Demo保持一致)
  • 配置 远程git Webhooks
    • 注意本Demo不是通过 git Webhooks 直接触发 http://configserverIp/actuator/bus-refresh 达到远程 git 配置文件更改时,通过rabbitmq 等一系列自动处理来各 微服务配置文件的更新。(这里其实是一个莫名其妙的坑,所以本项目采用了投机取巧的办法来达到远程配置更改,动态刷新的需求)具体逻辑如下:
    1. 创建一个类 ,用来向外界暴露一个 api接口,此接口的作用就是通过 http 模拟一个 post 请求,来触发 http://configserverIp/actuator/bus-refresh 接口,以达到动态刷新。
    /**
     * 远程 git webhooks ,调用此接口,由此接口发起 http post 请求去,触发bus-refresh 接口
     * 通过 rabbitmq 等一系列 默认处理机制就可以实现动态刷新机制
     *
     * @throws IOException
     */
    @PostMapping("postRefresh")
    public void httpPostJSON() throws IOException {
        // 模拟 http 请求
        DefaultHttpClient httpClient = new DefaultHttpClient();
        String url = "http://stvyc4.natappfree.cc/actuator/bus-refresh";
        HttpPost httpPost = new HttpPost(url);
        // 设置请求的header
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
        // 执行请求
        HttpResponse response = httpClient.execute(httpPost);
    }
    
    1. 在 远程 git webhooks 处配置地址为 postRefresh api接口
    • github 示例

  • gitlab 示例

内网穿透

https://natapp.cn/(此网站可以提供免费的内网穿透服务,可以让你的项目被外网访问,具体使用请百度,这里不做累述)

项目源码(可配合本文重点及源码理解)

github: https://github.com/tangzhiqiang/springcloudConfig-bus.git
码云:https://gitee.com/txiaoqiang/springcloudConfig_bus.git

项目准备(eureka 不做累述,可以使用自己项目的eureka作注册中心)

config server 项目准备
  • 依赖添加(重要部分)
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.BUILD-SNAPSHOT</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.BUILD-SNAPSHOT</spring-cloud.version>
    </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-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--rabbitmq 与 bus 的集成依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!--开放 monitor ,以便远程 git端 webhooks 可以push-->
        <!--因本Demo 采用此方案存在重大 bug ,故本项目不采用此方案-->
        <!--<dependency>-->
            <!--<groupId>org.springframework.cloud</groupId>-->
            <!--<artifactId>spring-cloud-config-monitor</artifactId>-->
        <!--</dependency>-->
        <!--监控接口-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

  • 项目配置文件
spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          # git 仓库地址
          uri: https://github.com/tangzhiqiang/testBus.git
#          search-paths: config-repo
          # git 账号
          username: 191####933@qq.com
          # git 密码
          password: 1######
          # 可以配置从远程 git 拉取配置信息时,本地暂时储存的位置,
          # 不配置就会按照默认路径存放,建议项目上线时配置,因为liunx下文件的读写权限问题
#          basedir: I:/test
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
# 开放 bus-refresh 接口,以便配合 bus 实现 配置的动态刷新
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh
server:
  port: 8089
  • 启动类

@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
@RestController
public class ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }

    /**
     * 远程 git webhooks ,调用此接口,由此接口发起 http post 请求去 
     * 触发bus-refresh 接口,通过 rabbitmq 等一系列 默认处理机制就可以实现动态刷新机制
     *
     * @throws IOException
     */
    @PostMapping("postRefresh")
    public void httpPostJSON() throws IOException {
        // 模拟 http 请求
        DefaultHttpClient httpClient = new DefaultHttpClient();
        String url = "http://stvyc4.natappfree.cc/actuator/bus-refresh";
        HttpPost httpPost = new HttpPost(url);
        // 设置请求的header
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
        // 执行请求
        HttpResponse response = httpClient.execute(httpPost);
    }
}
config client 项目准备
  • 依赖添加(不同处)依赖于config server 只有下面的配置不同
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>
  • 项目配置文件(因声明为bootstrap.yml或bootstrap.properties)

    • 注意:这里存在加载顺序问题

    bootstrap.yml(bootstrap.properties)先加载 application.yml(application.properties)后加载

spring:
  application:
    # 读取远程配置文件时 ,文件的前缀 (order-test.yml)
    name: order
  cloud:
    # 从配置中心读取远程配置
    config:
      discovery:
        # 必须设置为true
        enabled: true
        # 配置中心 服务名
        service-id: CONFIG
      # 读取远程配置文件时 ,文件的后缀 (order-test.yml)
      profile: test
# 向eureka 注册
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8086
  • 启动类(只需要注册到eureka就可,不用声明为 config clien)
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {

	public static void main(String[] args) {
		SpringApplication.run(OrderApplication.class, args);
	}
}