SpringCloud Config应用(SpringCloud Config Bus)


本文通过搭建一个eureka注册中心,config配置中心,以及两个configclient客户端来演示springlcoud config的基本使用以及通过spring cloud config bus来实现配置项的动态刷新。

1.项目搭建

在这里插入图片描述

1.1父项目

<?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>

    <groupId>com.gupaoedu.springcloud</groupId>
    <artifactId>spring-cloud-netflix</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>


    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
    </properties>

    <modules>
        <module>spring-cloud-eureka-server-9090</module>
        <module>spring-cloud-config-server-9091</module>
        <module>spring-cloud-user-service-8081</module>
        <module>spring-cloud-order-service-8082</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <!-- import 导入springboot springcloud的依赖包 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

1.2 注册中心搭建

spring-cloud-eureka-server-9090 ,引入eureka 依赖:spring-cloud-starter-netflix-eureka-server

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.gupaoedu.springcloud</groupId>
        <artifactId>spring-cloud-netflix</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.gupaoedu.example</groupId>
    <artifactId>spring-cloud-eureka-server-9090</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-eureka-server-9090</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 注册中心application.properties 配置
spring.application.name=spring-cloud-eureka-server-9090
server.port=9090
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:9090/eureka
  • @EnableEurekaServer开启注册中心
package com.gupaoedu.example.springcloudeurekaserver9090;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaServer9090Application {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringCloudEurekaServer9090Application.class, args);
    }
}

1.3 配置中心搭建

搭建配置中心,需要引入如下依赖:

  • spring-cloud-config-server 配置中心服务端
  • spring-cloud-starter-netflix-eureka-client 配置中心需要作为eureka客户端注册到注册中心
  • spring-boot-starter-actuator 手动刷新配置项
  • spring-cloud-config-monitor 自动刷新配置项
  • spring-cloud-starter-bus-kafka 使用kafka作为springcloud config bus消息总线
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.gupaoedu.springcloud</groupId>
        <artifactId>spring-cloud-netflix</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.gupaoedu.example</groupId>
    <artifactId>spring-cloud-config-server-9091</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-config-server-9091</name>
    <description>Demo project for Spring Boot</description>

    <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>

        <!-- 测试kafka作为分布式配置中心的消息总线,configserver以及configclient都需要添加cloud-bus以及actuator依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-kafka</artifactId>
        </dependency>
<!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
        <!--        </dependency>-->

        <!-- 需要把spring-boot-starter-actuator依赖去掉,否则configclient无法连接到配置中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-monitor</artifactId>
        </dependency>
    </dependencies>
</project>
spring:
  application:
    name: spring-cloud-config-server-9091
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/liuch890228/spring-cloud-config-server.git
          search-paths: spring-cloud-config-server
    bus:
      enabled: true # 开启bus
      trace:
        enabled: true
      refresh:
        enabled: true
  kafka:
    bootstrap-servers: localhost:9092 #kafka地址
    consumer:
      group-id: config-server # 分组,不同的组可以收到相同的消息
server:
  port: 9091
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka
  #kafka
  # 通过bus刷新外部配置
  # 通过调用/actuator/refresh接口刷新配置
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh
  • kafka安装与启动
    windows安装kafka

  • 开启配置中心configserver和eurekaclient

package com.gupaoedu.example.springcloudconfigserver9091;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableConfigServer
@EnableEurekaClient
@SpringBootApplication
public class SpringCloudConfigServer9091Application {
    
    

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

1.4 order-service搭建

1.4.1 ordre-service 父项目

<?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>

  <!-- 添加父pom依赖,这样user-service-provider项目能够直接依赖到spring-cloud-netflix根项目依赖的jar包 -->
  <parent>
    <groupId>com.gupaoedu.springcloud</groupId>
    <artifactId>spring-cloud-netflix</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <groupId>com.gupaoedu.springcloud</groupId>
  <artifactId>spring-cloud-order-service-8082</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <modules>
    <module>order-service-api</module>
    <module>order-service-provider</module>
  </modules>
  <name>spring-cloud-order-service-8082</name>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
</project>

1.4.2 order-service-api 子项目

  • 加入spring-cloud-starter-openfeign 依赖,对外提供Feign接口定义
<?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">
    <parent>
        <artifactId>spring-cloud-order-service-8082</artifactId>
        <groupId>com.gupaoedu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>order-service-api</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>
  • API接口定义
package com.gupaoedu.springcloud;
import com.gupaoedu.springcloud.dto.OrderDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
public interface OrderService {
    
    
    @GetMapping("/orders")
    String orders();
    @PostMapping("/order")
    int insert(OrderDto dto);  // OrderDto 一个属性  String orderId
}

openFeign接口定义

package com.gupaoedu.springcloud.clients;
import com.gupaoedu.springcloud.OrderService;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient("order-service")
public interface OrderServiceFeignClient extends OrderService{
    
    
}

1.4.3 order-service-provider 子项目

  • 提供openfeign接口的实现需要添加下面的依赖

spring-cloud-starter-config
spring-cloud-starter-netflix-eureka-client 注册到注册中心
spring-cloud-config-client 从configserver读取配置信息
pring-boot-starter-actuator 提供刷新配置的监控功能
spring-cloud-starter-bus-kafka 使用kafka作为springcloud config 分布式配置中心的消息总线

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.gupaoedu.springcloud</groupId>
        <artifactId>spring-cloud-order-service-8082</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.gupaoedu.example</groupId>
    <artifactId>order-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order-service-provider</name>
    <description>Demo project for Spring Boot</description>
    <dependencies>
        <dependency>
            <groupId>com.gupaoedu.springcloud</groupId>
            <artifactId>order-service-api</artifactId>
        </dependency>

        <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.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

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

        <!-- 测试kafka作为分布式配置中心的消息总线-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>com.gupaoedu.springcloud</groupId>
            <artifactId>order-service-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
  • bootstrap.yml启动配置
# 外部化配置,放到bootstrap.yml中优先加载!!!
spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: spring-cloud-config-server-9091
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka
  • 常规配置
spring:
  application:
    name: order-service
  cloud:
    bus:
      enabled: true
      trace:
        enabled: true
        refresh:
          enabled: true
      kafka:
        bootstrap-servers: localhost:9092 #kafka地址
        consumer:
          group-id: order-service # 分组,不同的组可以收到相同的消息
server:
  port: 8082
  # 1.添加springboot-starter-actuator依赖;  # 2.开放自动刷新端点,同时还需要在刷新配置的地方加上@Refresh注解
  # 3.通过调用/actuator/refresh接口刷新配置
management:
  endpoints:
    web:
      exposure:
        include: refresh
  • 启动类
package com.gupaoedu.example.orderserviceprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;
// controller包不是OrderServiceProviderApplication所在的子包,需要指定包扫描路径。
@ComponentScan(basePackages="com.gupaoedu.example.controller")
@EnableEurekaClient
@SpringBootApplication
public class OrderServiceProviderApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderServiceProviderApplication.class, args);
    }
}
  • order-service openfeign接口实现
package com.gupaoedu.example.orderserviceprovider;

import com.gupaoedu.springcloud.OrderService;
import com.gupaoedu.springcloud.dto.OrderDto;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderServiceImpl implements OrderService {
    
    
    @Override
    public String orders() {
    
    
        return "Return All Orders";
    }
    @Override
    public int insert(OrderDto dto) {
    
    
        return 0;
    }
}
  • 配置项测试类
package com.gupaoedu.example.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope  // 配置项有更新后,重新读取新的配置项
@RestController
public class ConfigController {
    
    
    @Value("${hello}")
    private String txt;
    @GetMapping("/config")
    public String config(){
    
    
        return txt;
    }
}

1.5 user-service搭建

1.5.1 user-service 父项目

<?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>

    <!-- 添加父pom依赖,这样user-service-provider项目能够直接依赖到spring-cloud-netflix根项目依赖的jar包 -->
    <parent>
        <groupId>com.gupaoedu.springcloud</groupId>
        <artifactId>spring-cloud-netflix</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.gupaoedu.springcloud</groupId>
    <artifactId>spring-cloud-user-service-8081</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>user-service-api</module>
        <module>user-service-provider</module>
    </modules>
</project>

1.5.2 user-service API接口

<?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">
    <parent>
        <artifactId>spring-cloud-user-service-8081</artifactId>
        <groupId>com.gupaoedu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>user-service-api</artifactId>
</project>

1.5.3 user-service 服务实现

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>spring-cloud-user-service-8081</artifactId>
        <groupId>com.gupaoedu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.gupaoedu.example</groupId>
    <artifactId>user-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service-provider</name>
    <description>Demo project for Spring Boot</description>

    <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.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • user-service 项目配置
    (1) 启动配置bootstrap.yml
    user-service 作为configserver的客户端,在启动时需要从配置中心获取外部配置,这个步骤需要在启动时完成,因此,注册中心eureka和配置中心configserver的相关配置要放到bootstrap.yml中去,否则项目启动会报错
spring:
  cloud:
    config:
      discovery:
        enabled: true # 不写默认是false,从8088端口查询外部配置项
        service-id: spring-cloud-config-server-9091
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka

(2)application.yml

spring:
  application:
    name: user-service
  cloud:
    bus:
      enabled: true
      trace:
        enabled: true
        refresh:
          enabled: true
      kafka:
        bootstrap-servers: localhost:9092 #kafka地址
        consumer:
          group-id: user-service # 分组,不同的组可以收到相同的消息
server:
  port: 8081
  # 刷新外部配置
  # 1.添加springboot-starter-actuator依赖;  # 2.开放自动刷新端点,同时还需要在刷新配置的地方加上@Refresh注解
  # 3.通过调用/actuator/refresh接口刷新配置
management:
  endpoints:
    web:
      exposure:
        include: refresh
  • 配置项读取测试代码
package com.gupaoedu.example.userserviceprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages ="com.gupaoedu.example" )
@EnableEurekaClient
@SpringBootApplication
public class UserServiceProviderApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(UserServiceProviderApplication.class, args);
    }
}
package com.gupaoedu.example.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope   // 动态刷新配置
@RequestMapping("/user")
public class ConfigController {
    
    
    @Value("${env}")
    private String text;
    @GetMapping("/config")
    public String getText(){
    
    
        return text;
    }
}

2 SpringCloud config配置应用

2.1 springcloud配置文件后缀组合方式

  • /{application}/{profile}/{label}
  • /{application}-profile
  • /{label} / {application} -{profile}
    application: 应用名称
    profile: 不同的配置分组
    在gitee上添加如下几个配置文件:
    order-service.yml
env:
  test
hello:
  mike666

user-service.properties

spring.application.name=user-service
server.port=8081
env=user-test12345

user-service-prd.properties

env=prd
timer.switch=off

user-service-dev.properties

env=dev

依次启动zookeeper ,kafka eureka-server ,config-server ,order-service ,user-service, 演示 /{application}-profile 这种后缀组合的效果:
先访问http://localhost:9091/user-service.properties,结果如下
在这里插入图片描述
访问 http://localhost:9091/user-service-prd.properties ,springcloud会自动合并user-service.properties 和user-service-prd.properties中的配置:
在这里插入图片描述
除此之外,它还可以支持以json , yml 格式读取配置:
在这里插入图片描述

2.2 spring-boot-starter-actuator 手动刷新配置

将configserver项目pom.xml文件中的spring-cloud-config-monitor和 spring-cloud-starter-bus-kafka的依赖注释掉,只用spring-boot-starter-actuator 来刷新配置项

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

这时如果git上的配置项有更新,configclient端要想更新配置项,必须要手动发送一个post请求给对应的项目的/actuator/refresh接口,才能读取到最新的配置。这种方式有个缺点,就是如果有几十个微服务,每个微服务都需要单独去调用/actuator/refresh接口更新配置才行。

2.3 springcloud config bus + webhook自动刷新配置

通过消息总线实现配置自动刷新,它的原理是当configserver上的配置有了更新,它会发送一个广播消息到消息队列中(kafka rabbitmq等),所有的configclient 会去订阅这些消息然后更新自己本地缓存的配置项,从而实现配置项的刷新。
如果引入spring-cloud-starter-bus-kafka 依赖,并启动kafka,此时又会出现一个问题:
修改了配置项之后用postman刷新总线消息:POST http://localhost:9091/actuator/bus-refresh, 虽然实现了对各个configclient 的配置项进行批量刷新,不需要对每个微服务项目单独调用actuator接口去点对点的同步配置项, 但是它仍然是手动的。有没有办法实现配置项变化自动去刷新呢? git的webhook功能就具备这个功能。通过webhook自动刷新配置,需要一个内网穿透工具,因为git无法直接访问到本地的localhost 地址,需要借助内网穿透工具webhook来让git 能够访问到localhost ,它的实现是 ,一旦webhook检测到配置更新的pull、request事件,就会去调用webhook中配置的地址去更新配置项:
首先启动ngrok
在这里插入图片描述
然后配置webhook
在这里插入图片描述
configserver引入spring-cloud-starter-bus-kafka 的依赖 ,然后启动erureka configserver , 以及configclient,这时修改gitee上的配置项,会看到项目中报错了:
在这里插入图片描述

2020-12-25 08:15:25.688  WARN 1356 --- [io-9091-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 315] (through reference chain: java.util.LinkedHashMap["commits"])]
2020-12-25 08:15:26.109  WARN 1356 --- [nio-9091-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (PushbackInputStream); line: 1, column: 54] (through reference chain: java.util.LinkedHashMap["pull_request"])]

无法解析json, 这是因为git发送的报文 无法被正确解析,webhook上面要改用monitor接口!需要在configserver中加入spring-cloud-config-monitor的依赖(configclient pom不用修改)

  <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>

        <!-- 测试kafka作为分布式配置中心的消息总线,configserver以及configclient都需要添加cloud-bus以及actuator依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-kafka</artifactId>
        </dependency>
<!--        <dependency>-->
<!--                    <groupId>org.springframework.boot</groupId>-->
<!--                    <artifactId>spring-boot-starter-actuator</artifactId>-->
<!--        </dependency>-->
        <!-- http://04b6c5e91673.ngrok.io/monitor   通过ngrok映射到本地9091 configserver调用/monitor接口,
        不会出现/actuator/bus-refresh接口推送配置项变更时json请求无法被config client解析的情况 -->
        <!-- 需要把spring-boot-starter-actuator依赖去掉,否则configclient无法连接到配置中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-monitor</artifactId>
        </dependency>
    </dependencies>

然后修改webhook 刷新配置url 的接口为monitor接口:
在这里插入图片描述
重启configserver,修改git上的 order-service.yml以及 user-service.properties 中的配置项:
在这里插入图片描述
请求http://localhost:8081/user/config ,可以看到配置项自己刷新了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就通过springcloudbus 消息总线实现了所有configclient上的配置的动态刷新!
代码地址

猜你喜欢

转载自blog.csdn.net/weixin_41300437/article/details/111802786