SpringCloud integrated Config distributed configuration center

Posted by eriksmoen on Tue, 07 Dec 2021 16:27:34 +0100

SpringCloud integrated Config distributed configuration center

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

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.

Operation steps

Spring cloud config is divided into 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 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.

effect

  • 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/crul access and refresh

Integrated configuration with GitHub

Since spring cloud config uses git to store configuration files by default (there are other ways, such as supporting SVN and local files), Git is the most recommended and is accessed in the form of http/https.

springcloud Config official website tutorial

Config configuration master control center construction

git common grammar review

git add file name : Add files from the workspace to the staging area
git commit -m "log information" file name : Commit files from staging area to local library
git clone Remote library address
git push -u origin master use master Branch to submit the contents of the local warehouse to the remote warehouse

Because github connection is slow, gitee is used instead

Create a new Repository named springcloud config on gitee with your own account.

Obtain the newly created gitee warehouse address from the previous step gitee warehouse address

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

  • The working directory is C:\Users\zdh\Desktop\springcloud config
  • git clone https://gitee.com/DaHuYuXiXi/springcloud-config.git

A folder named springcloud config is created in the working directory

Create three configuration files in the springcloud config folder, and then upload git add., git commit -m "sth." and other upload operations to the new Repository of springcloud config.

  • config-dev.yml
config:
  info: "master branch,springcloud-config/config-dev.yml version=7"
  • config-prod.yml
config:
  info: "master branch,springcloud-config/config-prod.yml version=1"
  • config-test.yml
config:
  info: "master branch,springcloud-config/config-test.yml version=1" 

The final step is to submit to the remote warehouse

Check the remote warehouse and find that the submission is successful

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

POM

<?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>cloud_Parent</artifactId>
        <groupId>dhy.xpy</groupId>
        <version>520.521.finally</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-center-3344</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Add message bus RabbitMQ support-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!--config rely on-->
        <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>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>
    
</project>

YML

server:
  port: 3344

spring:
  application:
    name:  cloud-config-center #Microservice name registered into Eureka server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/DaHuYuXiXi/springcloud-config.git #gitee the GIT warehouse name above
          ####search for directory
          search-paths:
            - springcloud-config
      ####Read branch
      label: master

#Service registration to eureka address
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

Main startup class

@SpringBootApplication
@EnableConfigServer #Other config uration center functions
public class ConfigCenterMain3344
{
    public static void main(String[] args) {
        SpringApplication.run(ConfigCenterMain3344.class, args);
    }
}

Modify the hosts file under windows and add mapping

C:\Windows\System32\drivers\etc
127.0.0.1 config-3344.com

Test whether the configuration content can be obtained from GitHub or gitee through the Config microservice

  • Start ConfigCenterMain3344
  • Browser anti question- http://config-3344.com:3344/master/config-dev.yml
  • Page return result:

Configure read rules

Official website

/{label}/{application}-{profile}.yml (recommended)

master branch

  • http://config-3344.com:3344/master/config-dev.yml
  • http://config-3344.com:3344/master/config-test.yml
  • http://config-3344.com:3344/master/config-prod.yml
  • http://config-3344.com:3344/config-dev.yml: if you don't write, the default is master

dev branch

  • http://config-3344.com:3344/dev/config-dev.yml
  • http://config-3344.com:3344/dev/config-test.yml
  • http://config-3344.com:3344/dev/config-prod.yml

/{application}-{profile}.yml

  1. http://config-3344.com:3344/config-dev.yml
  2. http://config-3344.com:3344/config-test.yml
  3. http://config-3344.com:3344/config-prod.yml
  4. http://config-3344.com:3344/config -Xxxx.yml (nonexistent configuration)

/{application}/{profile}[/{label}]

  • http://config-3344.com:3344/config/dev/master
  • http://config-3344.com:3344/config/test/master
  • http://config-3344.com:3344/config/test/dev

Summary of important configuration details

  • /{name}-{profiles}.yml
  • /{label}-{name}-{profiles}.yml
  • label: Branch
  • Name: service name
  • profiles: environment (dev/test/prod)

The configuration information is successfully obtained through GitHub or gitee with spring cloud config

Config client configuration and testing

Create cloud-config-client-3355

POM

<?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>cloud_Parent</artifactId>
        <groupId>dhy.xpy</groupId>
        <version>520.521.finally</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-client-3355</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Add message bus RabbitMQ support-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!--config client-->
        <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.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>
</project>

bootstrap.yml

applicaiton.yml is a user level resource configuration item

bootstrap.yml is system level, with higher priority

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 Environment obtained from the outside.

Bootstrap properties have high priority. By default, they are not overwritten by 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 configuration.

It is crucial 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 client configuration
    config:
      label: master #Branch name
      name: config #Profile name
      profile: dev #Read the suffix name and the above three combinations: the configuration file of config-dev.yml on the master branch is read http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 # configuration center address k


#Service registration to eureka address
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

Difference between application.yml and bootstrap.yml

Modify the config-dev.yml configuration and submit it to gitee, such as adding a variable age or version number version

Main start

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

Business class

@RestController
public class ConfigClientController
{
    //Expose the configuration information as a rest port
    @Value("${config.info}")
    private String configInfo;

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

test

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

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

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

  • Start 3355 as a Client to prepare for access

http://localhost:3355/configInfo

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

Dynamic refresh of distributed configuration

  • Linux operation and maintenance 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 ConfigClient client
  • 3355 does not change unless you restart or reload yourself
  • It is so difficult that every time the O & M modifies the configuration file, the client needs to restart?? nightmare

Modified version a 520

View configuration center

View client

Not repaired

Manual version of Config dynamic refresh

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

Dynamic refresh steps:

Modify 3355 module

POM introduces actor monitoring

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

Modify YML and add exposure monitoring port configuration:

# Exposure monitoring endpoint
management:
  endpoints:
    web:
      exposure:
        include: "*"     

@RefreshScope business class Controller is modified, and this annotation is added to the client

@RestController
@RefreshScope
public class ConfigClientController
{
    //Expose the configuration information as a rest port
    @Value("${config.info}")
    private String configInfo;

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

test

At this time, modify the contents of github configuration file - > access 3344 - > access 3355

http://localhost:3355/configInfo

3355 did you change??? No, one more step

How

The operation and maintenance personnel need to send a Post request to refresh 3355

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

Retest

http://localhost:3355/configInfo

3355 did you change??? Changed.

The client 3355 is successfully refreshed to the latest configuration content to avoid service restart

Remote warehouse modification

Central configuration center view

The client before post refresh is not sent

After sending

The client has also been updated

Think about what else?

  • 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 to find the method

Introduce the next Bus