SpringCloud -- Config and Bus parsing

1,Config

1.1 overview

1. Problems faced by distributed

  • Microservice means to split the business in a single application into one sub service. The granularity of each service is relatively small, so there will be a large number of services in the system. Because each service needs the necessary configuration information to run, a centralized and dynamic configuration management facility is essential.

2. What is config

  • Spring Cloud Config is divided into server and client.
  • The server also becomes a distributed configuration center. It is an independent micro service application, which is used to connect to the configuration server and provide access interfaces for the client to obtain configuration information, encryption / decryption information and so on.
  • The client manages application resources and business-related configuration contents through the specified configuration center, and obtains and loads configuration information from the configuration center at startup. The configuration server uses git to store configuration information by default, which is helpful for version management of environment configuration, And the GIT client tool can be used to manage and access the configuration content conveniently.

3. What can I do

  1. Centrally manage profiles
  2. Different environments have different configurations, dynamic configuration updates, and deployment by environment, such as dev/test/prod/beta/release
  3. The configuration is dynamically adjusted during operation. It is no longer necessary to write configuration files on each service deployed machine. The service will uniformly pull and configure its own information from the configuration center
  4. When the configuration changes, the service can sense the configuration changes and apply the new configuration without restarting
  5. Expose the configuration information in the form of REST interface

Official website address

1.2 configuration and test of Config server

1. Build Module

  • The name of the Module is cloud-config-center-3344.

2. Change 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>
        <dependency>
            <groupId>com.xiao</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>

3. Change YML

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  profiles:
    active: dev
  cloud:
    config:
      server:
        git:
          uri:  https://gitee.com/henryxjh/springcloud-config.git # url address
          search-paths: # Search path
            - springcloud-config
      label: master  # The main branch is configured



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

4. Main startup

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

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

5. Test results

(1) . other access path formats

/{application}/{profile}[/{label}]
/{application}-{profile}.yml   ## This is recommended
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

1.3 configuration and test of Config client

1. Build Module

  • The name of the Module is cloud-config-client-3355.

2. Change POM

   <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.xiao</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>

3. Change YML

server:
  port: 3355

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


  • To add application Change the yaml file name to bootstrap Yaml is the key, bootstrap Yaml is better than application Yaml is loaded first. And it is system level with higher priority.
  • SpringCloud will create a Bootstrap Context as the parent context of the Application Context of the Spring application. During initialization, the Bootstrap Context is responsible for loading configuration properties from an external source and parsing the configuration. The two contexts share an Environment obtained from the outside.

4. Main startup

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

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

5. Controller class

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {

    @Value("${spring.application.name}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return configInfo;
    }
}

6. Test results

  • As shown in the figure, we successfully read the content from the corresponding configuration file.

1.4. Dynamic refresh of Config client (manual version)

1.4.1 problems faced

  1. Linux operation and maintenance modifies the content of the configuration file on GitHub to make adjustments

  2. Refresh 3344 and find that the ConfigServer configuration center responds immediately

  3. Refresh 3355 and find no response from ConfigServer client

  4. 3355 does not change unless you restart or reload yourself

1.4.2 dynamic refresh configuration and test

1. Introduction of POM into actor monitoring

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

2. Add the following code to the yml file

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

3. Modify the controller class

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;

@RestController
@RefreshScope
public class ConfigClientController {

    @Value("${spring.application.name}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return configInfo;
    }
}

4. You need to send a request to refresh the client

curl -X POST "http://localhost:3355/actuator/refresh"

5. Test results

(1) , access port 3344

(2) , access port 3355

2,Bus

2.1 overview

1. What is it

  • Spring Cloud Bus is a framework used to connect the nodes of distributed systems with lightweight messaging systems. It integrates the event processing mechanism of Java and the functions of message middleware. Spring Cloud Bus currently supports RabbitMQ and Kafka.
  • In microservice architecture systems, lightweight message brokers are usually used to build a common message topic and connect 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. In each instance of the bus, you can easily broadcast some messages that need to be known to other instances connected to the subject.
  • The principle is that all ConfigClient instances listen to the same topic in MQ, and the default is SpringCloudBus. When a service refreshes the data, it will put this message into the topic, so that other services listening to the same topic can be notified, and then update their own configuration.

2. What can I do

  • Spring Cloud Bus can manage and propagate messages between distributed systems, just like a distributed actuator. It can be used to broadcast state changes, time push, etc. it can also be used as a communication channel between microservices.

2.2. Dynamic refresh in the form of global broadcast

2.2.1. Add a new client

1. Build Module

  • The name of the Module is cloud-config-client-3366.

2. Change POM

<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.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</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>

3. Change YML

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: "*"
 

4. Main startup

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

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

5. controller class

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;

@RestController
@RefreshScope
public class ConfigClientController {

    @Value("${spring.application.name}")
    private String serverPort;

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


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


}
 

2.2.2. Two methods of global dynamic refresh

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

  1. Use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients (more recommended)

(1) The second architecture is more appropriate

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

2.2.3. Add the configuration supported by the message bus

1. Add message bus support to cloud-config-center-3344 configuration center server

(1),POM

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

(2) . newly added YML content

rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: 123456

2. Add message bus support to cloud-config-center-3355 client

(1),POM

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

(2) . newly added YML content

rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: 123456

3. Add message bus support to cloud-config-center-3366 client

(1),POM

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

(2) . newly added YML content

rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: 123456

2.2.4 test results

  • After sending the request curl - x post“ http://localhost:3344/actuator/bus -The test results after "Refresh" are as follows

  • One amendment, broadcast notice, takes effect everywhere.

2.3 dynamic refresh in the form of fixed-point notification

  • In the above environment in subsection 2.2, the request to notify only 3355 and not 3366 is as follows:
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

Keywords: Java Back-end Spring Cloud Microservices

Added by reyes99 on Mon, 17 Jan 2022 22:47:39 +0200