The word count: 1.1 k words | reading time material 4 points

In previous articles, I covered the basics of the unified configuration center (server and client) and demonstrated the entire process from configuring a Git repository to pulling a configuration. See the Unified Configuration Center blog. In this blog post we mentioned, but not demonstrated or implemented, that the unified configuration center has the benefit of dynamically updating configuration files without having to manually restart the service. This article describes how to automatically refresh the configuration through Spring Cloud Bus and how it works.

It is necessary to realize automatic configuration refresh. Let’s take a look at the principle of automatic configuration refresh using Spring Cloud Bus, as shown below:

Spring Cloud Bus provides a mechanism for batch refreshing configurations. It uses lightweight message brokers (such as RabbitMQ, Kafka, etc.) to connect nodes of distributed systems so that configuration changes and other administrative instructions can be broadcast through Spring Cloud Bus. All instances of the SHOP service are connected together through the message bus, and each instance subscribes to configuration update events. When the/bus/ Refresh endpoint of one of the microservice nodes is requested, that instance sends a configuration update event to the message bus, and the other instances get that event and update the configuration.

1. Introduce dependencies and configurations

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Copy the code

Spring Cloud Bus uses a message queue to automatically refresh the configuration, so you need to enable a message queue and configure the message queue in the configuration file. I used RabbitMQ:

spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/zouchanglin/config-repo
          username: zouchanglin
          password: 00001010101
          basedir: /root/config
  rabbitmq:
    host: 192.168.79.128
    port: 5672
    username: guest
    password: guest
    
eureka:
  instance:
    appname: config
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka
Copy the code

After the unified configuration center and Client are started, the corresponding message queues can be seen:

2. Expose the update interface

POST http://localhost:8080/actuator/bus-refresh
Copy the code

After you request the interface in POST mode, the unified configuration center knows that the configuration in the Git repository has changed, and automatically pulls the latest configuration. Then the Unified configuration center sends the message to the message queue. The Config Client consumes the message and pulls the latest configuration from the configuration center, and automatically updates the configuration. However, the interface of the actuator/bus-refresh interface needs to be exposed and Git WebHook can access it. Therefore, the following contents need to be added in the configuration file of the unified configuration center:

spring: application: name: config cloud: config: server: git: uri: https://gitee.com/zouchanglin/config-repo username: Basedir: /root/config rabbitmq: host: 192.168.79.128 Port: 5672 username: Use the actuator/bus-refresh interface in the operating system. Management: endpoints: web: exposure: include instance: appname: config client: service-url: defaultZone: http://localhost:8762/eurekaCopy the code

After updating the configuration file, restart the unified Configuration Center.

3. Declare the automatic update scope

Shop-dev. yml is configured as follows, and its env attribute is dev

server:
  port: 8090

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka/

spring:
  application:
    name: shop
  rabbitmq:
    host: 192.168.79.128
    port: 5672
    username: guest
    password: guest
env: dev
Copy the code

When testing the content of the configuration file, we wrote this Controller, and now we need to add a new @refreshScope annotation, which actually declares the scope of automatic configuration update, so we need to add @refreshScope annotation:

@RestController @RequestMapping("/env") @RefreshScope public class EnvController { @Value("${env}") private String env; @GetMapping("print") public String printEnv(){ return env; }}Copy the code

Instead of doing this, we tend to centralize the configuration and declare it on top of the configuration class, assuming that the current Git repository’s shop-dev.yml configuration looks like this:

server:
  port: 8090

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka/

spring:
  application:
    name: shop
  rabbitmq:
    host: 192.168.79.128
    port: 5672
    username: guest
    password: guest
env: dev

boy:
  name: Tim
  age: 18
Copy the code

Create a new JavaBean called Boy in the config directory, and add @refreshScope to the Boy:

package xpu.edu.shop_service.config;

@Data
@Component
@ConfigurationProperties(prefix = "boy")
@RefreshScope
public class Boy {
    private String name;
    private int age;
}
Copy the code

At this point, the Controller is changed as follows:

@RestController @RequestMapping("/env") public class EnvController { @Autowired private Boy boy; @GetMapping("print") public String printEnv(){ return "name:" + boy.getName() + " age:" + boy.getAge(); }}Copy the code

Using the /actuator/bus-refresh interface manually, the refresh is achieved, as shown in the following figure:

When updates or other events occur, the /actuator/bus-refresh interface is automatically accessed by the Git-hosting platform and the configuration files are automatically refreshed.