Config configuration center

Learning objectives


Article reprint Le byte

Service configuration status

Configuration files are familiar to us. In the microservice system, each microservice not only has code, but also needs to connect other resources, such as database configuration or functional switch MySQL, Redis, Security and other related configurations. In addition to the basic configuration of project operation, there are some configurations related to our business, such as seven cattle storage, SMS and email, or some business switches.

However, with the continuous iteration of the microservice system, the whole microservice system may become a network structure. At this time, the scalability, scalability, coupling and so on of the whole microservice system should be considered. One of the most important links is configuration management.

Disadvantages of general configuration management solutions

  • Hard coding (code modification, cumbersome and high risk)
  • properties or yml (replacement and restart are required in the cluster environment)
  • xml (repackaging and restarting)

Why use Spring Cloud Config

Because conventional configuration management has great disadvantages, the centralized configuration center of Spring Cloud Config is used to manage the configuration information of each service.

Spring Cloud Config provides extensible configuration services in the way of Server server and Client client in the micro service distributed system. The Server provides the storage of the configuration file and provides the content of the configuration file in the form of interface; The Client obtains data through the interface and initializes its own application based on this data.

The configuration center is responsible for managing various environment profiles of all services.

The configuration center stores configuration files in Git by default, so we can easily deploy and modify them, which is helpful for version management of environment configuration.

What problems does Spring Cloud Config solve

Spring Cloud Config solves the problems of centralization, version control, platform independence and language independence of microservice configuration. Its characteristics are as follows:

  • Provide server and client support (Spring Cloud Config Server and Spring Cloud Config Client)
  • Application deployment in centralized management distributed environment
  • Encryption and decryption of attribute values (symmetric and asymmetric encryption)
  • Seamless integration with Spring applications based on Spring environment
  • A program that can be developed in any language
  • The default implementation is based on Git, and version management can be performed

Next, we will mainly talk about the use of Config from the following sections.

  1. Configuration center of basic version (without integration of Eureka)
  2. Integrated Eureka version of the configuration center
  3. Automatic refresh of configuration based on actor
  4. Encryption and decryption of attribute values (symmetric and asymmetric encryption)
  5. Automatic refresh of configuration based on Spring Cloud Bus

Environmental preparation

project

Config demo aggregation project.

  • Eureka server: Registration Center (used to integrate the configuration center of Eureka version)
  • eureka-server02: Registry (used to integrate the configuration center of Eureka version)
  • Order service: order service (used to integrate the configuration center of Eureka version)

Warehouse

Config repo warehouse.

  • Repository name: warehouse name
  • Description (optional): warehouse description
  • Public, Private: warehouse permission (public sharing, Private or designated partner)
  • Initialize this repository with a README: add a readme md
  • Add .gitignore: generate corresponding files for file types that do not require version management gitignore
  • Add a license: certificate type, and generate the corresponding file LICENSE

configuration file

The configuration files of different environments are uploaded to the config repo warehouse.

The name of the configuration file is not random. For example, config-client-dev.yml and config-client-prod.yml are different environments of the same project. The project name is config client, one corresponds to the development environment and the other corresponds to the formal environment. Test represents the test environment.

config-client.yml

server:
  port: 7777 # port

spring:
  application:
    name: config-client # apply name

# Custom configuration
name: config-client-default

config-client-dev.yml

server:
  port: 7778 # port

spring:
  application:
    name: config-client # apply name

# Custom configuration
name: config-client-dev

config-client-test.yml

server:
  port: 7779 # port

spring:
  application:
    name: config-client # apply name

# Custom configuration
name: config-client-test

config-client-prod.yml

server:
  port: 7780 # port

spring:
  application:
    name: config-client # apply name

# Custom configuration
name: config-client-prod

Introductory case

Introductory case explanation: configuration center of basic version (without integration of Eureka)

Create server

Create the sub project config server under the config demo parent project.

Add dependency

Add spring cloud config server dependency, complete POM The XML file is as follows:

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>config-server</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Inherit parent dependency -->
    <parent>
        <groupId>com.xxxx</groupId>
        <artifactId>config-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring cloud config server rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

configuration file

server:
  port: 8888 # port

spring:
  application:
    name: config-server # apply name
  cloud:
    config:
      server:
        git:
          uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file
          #username:             # Login account of Github and other products
          #password:             # Login password of Github and other products
          #default-label: master # Profile branch
          #search-paths:         # Root directory of configuration file

Startup class

Add @ EnableConfigServer annotation to the startup class.

package com.xxxx;

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

// Configuration center server annotation
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }

}

Access rules

Spring Cloud Config has a set of access rules. We can directly access it on the browser through this set of rules.

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
  • {application}: application name (target service name)
  • {profile}: get the specified environment configuration. The project includes development environment, test environment and production environment. The corresponding configuration file is based on Application - {profile} YML, such as application-dev.yml and application test yml,application-prod.yml. The default value is default.
  • {label}: indicates the git branch. The default is the master branch. If the project is distinguished by branches, you can control access to different configuration files through different labels.

Create client

Create the sub project config client under the config demo parent project.

Add dependency

Add spring cloud starter config dependency, complete POM The XML file is as follows:

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>config-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Inherit parent dependency -->
    <parent>
        <groupId>com.xxxx</groupId>
        <artifactId>config-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring cloud starter config rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!-- spring boot web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

configuration file

The client configuration file name must be called bootstrap yml

spring:
  cloud:
    config:
      name: config-client # The name of the configuration file corresponds to the first half of the configuration file in the git warehouse
      uri: http://Localhost: 8888 # config server server server address
      label: master # git branch
      profile: default # Specify environment

Control layer

Add a RestController to test and obtain configuration file information.

package com.xxxx.controller;

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

@RestController
public class ConfigController {

    @Value("${name}")
    private String name;

    @GetMapping("/name")
    public String getName() {
        return name;
    }

}

Startup class

package com.xxxx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }

}

test

Modify the configuration file to dev environment:

spring:
  cloud:
    config:
      name: config-client # Application name, corresponding to the first half of the configuration file in git warehouse
      uri: http://Localhost: 8888 # config server server server address
      label: master # git branch
      profile: dev # Specify environment

Spring Cloud Config high availability

The above describes the most basic usage of Spring Cloud Config. If Eureka is used as the service registration and discovery center in our project, Spring Cloud Config should also be registered with Eureka to facilitate the use of other services, and multiple configuration center servers can be registered to achieve high availability.

Next, integrate Spring Cloud Config into Eureka. You can read my history articles about Eureka.

Add profile

Add configuration files in Github repository.

order-service-dev.yml

server:
  port: 9090 # port

spring:
  application:
    name: order-service # apply name

# Configure Eureka Server registry
eureka:
  instance:
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # Set service registry address
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

# Custom configuration
name: order-service-dev

order-service-prod.yml

server:
  port: 9091 # port

spring:
  application:
    name: order-service # apply name

# Configure Eureka Server registry
eureka:
  instance:
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # Set service registry address
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

# Custom configuration
name: order-service-prod

Integrated registry

The case has been prepared for you. You can use it directly without creating a registration center. For clarity, post the dependency and configuration information to you.

rely on

The core dependencies of Eureka server and Eureka Server02 are consistent.

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>eureka-server</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Inherit parent dependency -->
    <parent>
        <groupId>com.xxxx</groupId>
        <artifactId>config-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- Project dependency -->
    <dependencies>
        <!-- netflix eureka server rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- spring boot web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

configuration file

Eureka server application yml

server:
  port: 8761 # port

spring:
  application:
    name: eureka-server # Application name (same under cluster)

# Configure Eureka Server registry
eureka:
  instance:
    hostname: eureka01            # Host name. If it is not configured, it will be obtained according to the host name of the operating system
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    # Set the service registry address and point to another registry
    service-url:                  # Registered address of the registry
      defaultZone: http://localhost:8762/eureka/

Application of eureka-server02 yml

server:
  port: 8762 # port

spring:
  application:
    name: eureka-server # Application name (same under cluster)

# Configure Eureka Server registry
eureka:
  instance:
    hostname: eureka02            # Host name. If it is not configured, it will be obtained according to the host name of the operating system
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    # Set the service registry address and point to another registry
    service-url:                  # Registered address of the registry
      defaultZone: http://localhost:8761/eureka/

Startup class

The core codes of Eureka server and Eureka Server02 startup classes are consistent.

package com.xxxx;

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

@SpringBootApplication
// Open EurekaServer annotation
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }

}

Spring Cloud Config server

Compared with the configuration center of the basic version, the server has more Eureka configuration, which is the same in other places.

After the config server server is built, a config Server02 is reproduced to achieve high availability.

rely on

The core dependencies of config server and config Server02 are consistent. Note the spring cloud config server dependency.

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>config-server</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Inherit parent dependency -->
    <parent>
        <groupId>com.xxxx</groupId>
        <artifactId>config-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring cloud config server rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!-- netflix eureka client rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

configuration file

Config server application yml

server:
  port: 8888 # port

spring:
  application:
    name: config-server # apply name
  cloud:
    config:
      server:
        git:
          uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file
          #username:             # Login account of Github and other products
          #password:             # Login password of Github and other products
          #default-label: master # Profile branch
          #search-paths:         # Root directory of configuration file

# Configure Eureka Server registry
eureka:
  instance:
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # Set service registry address
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

Application.config-server02 yml

server:
  port: 8889 # port

spring:
  application:
    name: config-server # apply name
  cloud:
    config:
      server:
        git:
          uri: https://github. Warehouse address of COM / XXXX / config repo # configuration file
          #username:             # Login account of Github and other products
          #password:             # Login password of Github and other products
          #default-label: master # Profile branch
          #search-paths:         # Root directory of configuration file

# Configure Eureka Server registry
eureka:
  instance:
    prefer-ip-address: true       # Whether to register with ip address
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # Set service registry address
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

Startup class

The core codes of config server and config Server02 startup classes are consistent.

package com.xxxx;

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

// Open the Eureka client annotation. If the Eureka registry is configured in the current version, the annotation will be opened by default
//@EnableEurekaClient
// Configuration center server annotation
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }

}

Spring Cloud Config client

After the client joins Eureka, it does not need to deal directly with the server of the configuration center, but accesses it through Eureka.

rely on

POM of order service xml. Note the spring cloud starter config dependency.

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxxx</groupId>
    <artifactId>order-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Inherit parent dependency -->
    <parent>
        <groupId>com.xxxx</groupId>
        <artifactId>config-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring boot web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- netflix eureka client rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- spring cloud starter config rely on -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

configuration file

Bootstrap of order service yml

spring:
  cloud:
    config:
      name: order-service # The name of the configuration file corresponds to the first half of the configuration file in the git warehouse
      label: master # git branch
      profile: dev # Specify environment
      discovery:
        enabled: true # open
        service-id: config-server # Specify the service ID of the configuration center server

Control layer

Add a RestController to test and obtain configuration file information.

package com.xxxx.controller;

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

@RestController
public class ConfigController {

    @Value("${name}")
    private String name;

    @GetMapping("/name")
    public String getName() {
        return name;
    }

}

Startup class

package com.xxxx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Open the Eureka client annotation. If the Eureka registry is configured in the current version, the annotation will be opened by default
//@EnableEurekaClient
@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

}

Article reprint Le byte

Keywords: Front-end Spring IDE

Added by mady on Fri, 21 Jan 2022 07:18:28 +0200