springcloud:config distributed configuration center and Bus message Bus, RabbitMQ environment configuration

springcloud

config distributed configuration center

Overview: configuration problems faced by distributed systems?

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.
Spring cloud provides ConfigServer to solve this problem. Each of our microservices carries an application.yml and manages hundreds of configuration files

Official website: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/

What is config?

SpringCloud Config provides centralized external configuration support for microservices in the microservice architecture. The configuration server provides a centralized external configuration for all environments of different microservice applications.

How do you do it?

SpringCloud Config is divided into two parts: server and client:

  • The server is also called distributed configuration center. It is an independent micro service application, which is used to connect to the configuration server and provide the client with access interfaces such as obtaining configuration information and encrypting / decrypting information

  • The client manages application resources and business-related configuration content 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, The GIT client tool can be used to manage and access the configuration content conveniently

What can we do with it?

  • Centrally manage profiles
  • Different environments have different configurations, dynamic configuration updates, and deployment by environment, such as dev/test/prod/beta/release
  • 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
  • When the configuration changes, the service can sense the configuration changes and apply the new configuration without restarting
  • Expose the configuration information in the form of REST interface: post, curl access and refresh

Preconditions

Integrated configuration with Github

Because spring cloud config uses git to store configuration files by default (there are other methods, such as supporting svn and local files, but Git is the most recommended, and http/https access is used)

Create a new Repository named spring cloud config on Github with your own account

Add these:

Create a new git warehouse and clone on the local hard disk

Hands on Combat

Config server configuration and test

Create a new Module cloud-config-center-3344, which is the Cloud configuration center Module cloudConfig Center

Import dependency

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

Related configuration

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri:  Fill in your own github route
          search-paths:
            - springcloud-config
      label: master
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:7001/eureka
 

Main start

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

Test whether the configuration content can be obtained from Github through the Config microservice

Start microservice 3344: http://config-3344.com:3344/master/config -dev.yml

Read rule

/{label}/{application}-{profile}.yml (this method is most recommended)

The configuration information is successfully obtained through GitHub with SpringCloud Config

Config client configuration and testing

New module cloud-config-client-3355

rely on

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

Why is bootstrap.yml written like this

applicaiton.ym1 is a user level resource configuration item. bootstrap.ym1 is a system level item with higher priority
I
Spring Cloud will create a "Bootstrap Context" as the parent context of the Application Context of the spring application. During initialization, BootstrapContext 'is responsible for loading configuration properties from external sources and parsing the configuration. The two contexts share an externally obtained Environment '.
The 'bootstrap') attribute has high priority, and by default, they will not be overwritten by the local configuration. Bootstrap context and Application Context have different conventions, so a 'bootstrap.yml' file is added to ensure the separation of bootstrap context and Application Context configurations.
It is very important to change the application.yml file under the Client module to bootstrap.yml,
Because bootstrap.yml is loaded before application.yml. Bootstrap.yml has higher priority than application.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

Main startup class

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

Business class

@RestController
public class ConfigClientController {

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

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

Start the Config configuration center 3344 micro service and conduct self-test

http://config-3344.com:3344/master/config-dev.yml

You can read the configuration file information in the git repository

Start 3355 as a Client to prepare for access

http://localhost:3355/configInfo

Access the configuration information of the configuration center

The client 3355 successfully accesses SpringCloud Config3344 and obtains configuration information through GitHub

Problems come at any time, dynamic refresh of distributed configuration

Scenario: Linux O & M modifies the content of the configuration file on GitHub to make adjustments

  • Refresh 3344 and find that the ConfigServer configuration center responds immediately
  • Refresh 3355 and find no response from ConfigServer client
  • 3355 does not change unless you restart or reload yourself

Does the client need to restart every time the O & M modifies the configuration file?? Nightmare!!!

Dynamic refresh of Config client

Avoid restarting the client micro service 3355 every time the configuration is updated

POM introduces actor monitoring

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

Modify the configuration to expose all the information

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

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

@RefreshScope business class Controller modification

@RefreshScope
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;

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

After configuration, the operation and maintenance personnel need to send a Post request to refresh 3355

  • Must be a Post request
  • Command line: curl -X POST“ http://localhost:3355/actuator/refresh ”

After the request

You can dynamically refresh the configuration without restarting

  • http://localhost:3355/configInfo
  • The client 3355 is successfully refreshed to the latest configuration content
  • Service restart is avoided

There are still remaining problems

At this time, new problems come again

If there are multiple microservice clients 3355 / 3366 / 3377....

Each microservice needs to execute a post request and refresh manually?

Can we broadcast one notice and take effect everywhere?

We want a wide range of automatic refresh and find methods. If there is a need, someone will solve it

Bus message bus

In a word

  • Distributed automatic refresh configuration function
  • Spring Cloud Bus can be used with Spring Cloud Config to dynamically refresh the configuration

What is Bus?

What can he do?

Why is it called a bus?

What is a bus:
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. Each instance on the bus can easily broadcast some messages that need to be known by other instances connected to the subject.
Basic principle:
ConfigClient instances listen to the same Topic in MQ (springcloudbus by default). When a service refreshes the data, it will put this information into the Topic, so that other services listening to the same Topic can be notified, and then update their own configuration.

RabbitMQ environment configuration

Install Erlang, download address: http://erlang.org/download/otp_win64_21.3.exe

Install RabbitMQ at: https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe

Enter the sbin directory under the RabbitMQ installation directory

D:\rabbitmq_server-3.7.14\sbin

Open the command line: rabbitmq plugins enable rabbitmq_ management

After execution, you can see

Visit the address to see if the installation was successful: http://localhost:15672/

Spring cloud bus dynamically refreshes global broadcast

You must have a good RabbitMQ environment first

Demonstrate the broadcast effect, increase the complexity, and then make another 3366 with 3355 as the template

Design idea

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

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

  • The architecture in Figure 2 is obviously more suitable, and the reasons why Figure 1 is not suitable are as follows

    • It breaks the single responsibility of microservices, because microservices are business modules, 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 a microservice is migrated, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications

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

pom

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

Update profile

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

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

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

management:
  endpoints:
    web:
      exposure:
        include: 'bus-refresh'
 
 

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

pom

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

to configure

server:
  port: 3355

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

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"
 

3366 and 3355 follow suit

test

Modify the configuration file on Github and increase the version number

Send Post request

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

Send once, take effect everywhere

View the configuration center

http://config-3344.com/config-dev.yml

View client

http://localhost:3355/configInfo

http://localhost:3366/configInfo

Get the configuration information and find that it has been refreshed. Once modified, broadcast the notice and take effect everywhere

Spring cloud bus dynamic refresh set specified notification

I don't want to be notified in full, but I just want to be notified at a fixed point

  • Notice only 3355
  • No notice 3366

Specify a specific instance to take effect instead of all

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 to update the configuration through the destination parameter class

After sending, you will find

Only 3355 have been updated

3366 not updated

Global notification flowchart

  • The request goes to the configserver first, and tells the configuration to be refreshed and whether to notify at a fixed point
  • config server pulls the corresponding configuration from git
  • Send a message to the message bus,
  • The message bus sends messages and the client receives them

Keywords: git RabbitMQ Spring Distribution Spring Cloud

Added by tuuga on Sat, 11 Sep 2021 08:20:57 +0300