Spring Cloud learning notes -- 10 Spring Cloud bus message bus

Posted by NS on Sun, 30 Jan 2022 16:17:36 +0100

In SpringCloud Config, if multiple microservice clients obtain configuration information from the service configuration center, once the configuration file in the remote library is modified, the service configuration center can update synchronously, but the modification of configuration information cannot be synchronized to each microservice immediately, We can update the configuration information by sending a post request to the micro service to refresh the micro service. We hope that: 1. Each micro service does not need to send a post request one by one or manually refresh one by one. A notification enables each micro service to obtain the latest configuration information; 2. Further, let the micro service that modifies the configuration information modify the information, and the micro service that does not modify the configuration information will not be modified.

Spring Cloud Bus is a framework used to link the nodes of distributed system with lightweight message system. It integrates the time processing mechanism of Java and the functions of message middleware. Specifically, it has the function of distributed automatic refresh configuration. Spring Cloud Bus can be used with Spring Cloud Config to realize the dynamic refresh of configuration; Currently, two message brokers are supported: RabbitMQ and Kafka

SpringCloud can manage and disseminate information between distributed systems, just like a distributed actuator, which can be used to broadcast state changes, time push, etc. it can also be used as a communication channel between microservices.

Main functions:

Bus

In microservice architecture systems, lightweight message brokers are usually used to build a common message topic and link all microservice instances in the system. Since the messages generated in this topic will be monitored and consumed by all instances, it is called message bus. Each instance on the bus can easily broadcast some messages that need to be known by other instances connected to the subject.

Basic principles

ConfigClient instances listen to the same Topic(Spring Cloud Bus) in MQ. When a service refreshes the data, it will put this information into the Topic, so that other micro services listening to the same Topic can be notified, and then update their own configuration.

RabbitMQ installation (Linux system)

Install Docker first and then run the following command: see the installation steps of Docker Official document of Docker
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

##############Set RabbitMQ auto start#######################
docker update rabbitmq --restart=always

##############Log in to the login page of RabbitMQ management side#################
http: / / server IP address: 15672

The default user name and password are guest

Spring cloud bus dynamically refreshes global broadcast

Add a new microservice module

To notify multiple microservices, you need to create a cloud-config-client-3366 module

1. POM file

<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>com.atyixuan</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </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>

2,bootstrap.yml profile

server:
  port: 3366

spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config
      profile: dev
      uri: http://localhost:3344
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"

3. Main startup class: com atyixuan. springcloud. ConfigClientMain3366

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

4. Business class: com atyixuan. springcloud. controller. ConfigClientController

@RestController
@RefreshScope
public class ConfigClientController {
    @Value("${server.port}")
    private String serverPort;

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

    @GetMapping(value = "/configInfo")
    public String getConfigInfo() {
        return "server port: " + serverPort + "\t\n\n configInfo: " + configInfo;
    }
}

design idea

1) Use the message bus to trigger a client / bus/refresh and refresh the configuration of all clients

2) use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients (more recommended). Compared with the following figure, the above figure is inappropriate for the following reasons:

  • It breaks the single responsibility of microservice, because microservice itself is a business module, which should not bear the responsibility of configuration refresh;
  • It destroys the peer-to-peer of micro service nodes;
  • There are certain limitations. For example, when migrating a microservice, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications

Modification of configuration center and two microservices

Add message bus support to cloud-config-center-3344 configuration center server and add new dependencies in its POM file:

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

Modify the YML configuration file:

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri:  https://github.com/hhf19906/springcloud-config.git  #git@github.com:hhf19906/springcloud-config.git
          search-paths:
            - springcloud-config
      label: master

  # Using rabbitMQ messaging middleware
  rabbitmq:
    host: The server IP address
    port: 5672
    username: guest
    password: guest


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

management:
  endpoints:
    web:
      exposure:
        # This corresponds to / bus/refresh in the figure above
        include: 'bus-refresh'

Add message bus support to cloud-config-center-3355 client and add new dependencies in its POM file:

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

Modify the YML configuration file:

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config
      profile: dev
      uri: http://localhost:3344
  rabbitmq:
    host: The server ip address
    port: 5672
    username: guest
    password: guest


eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

management:
  endpoints:
    web:
      exposure:
        include: "*"

Add message bus support to cloud-config-center-3366 client and add new dependencies in its POM file:

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

Modify the YML configuration file:

server:
  port: 3366

spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config
      profile: dev
      uri: http://localhost:3344

  rabbitmq:
    host: The server ip address
    port: 5672
    username: guest
    password: guest

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

management:
  endpoints:
    web:
      exposure:
        include: "*"

Test:

Start in sequence

cloud-eureka-server7001
cloud-config-center3344
cloud-config-client-3355
cloud-config-client-3366 Enter in the browser: http://config-3344.com:3344/config-dev.yml

 http://localhost:3355/configInfo

 http://localhost:3366/configInfo

At this time, modify the configuration information in the remote Git and change the version number to 5

Use curl to send a POST request to refresh cloud-config-center3344

curl -X POST "http://localhost:3344/actuator/bus-refresh"

  http://localhost:3355/configInfo Browser access again http://localhost:3355/configInfo And http://localhost:3366/configInfo

The results are as follows:

The configuration information obtained by the two microservices has been updated, realizing the purpose of one modification and taking effect everywhere

Spring cloud bus dynamic refresh fixed-point notification

In the previous step, we realized the dynamic refresh of the global broadcast. We hope to further let only some micro services receive notifications, and some micro services do not receive notifications.

Formula: http://localhost: Port number of configuration center / Actor / bus refresh / {destination}

/The bus/refresh request is no longer sent to the specific service instance, but to the config server and specifies the service or instance that needs to update the configuration through the destination parameter class

According to the above micro service, only cloud-config-client-3355 will be notified and cloud-config-client-3366 will not be notified

When refreshing the service configuration center cloud-config-center3344, only refresh cloud-config-client-3355

curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

Modify the content of the configuration file in Git remote library again

Curl refresh cloud-config-center3344

cloud-config-client-3355 received the notification, but cloud-config-client-3366 did not

The whole process is shown in the figure below

Topics: Java Back-end Spring Cloud