SpringCloud Config distributed configuration center

Posted by umbra on Tue, 19 Oct 2021 21:03:36 +0200

Distributed configuration center overview

1. Configuration problems faced by distributed systems?

Microservice means to split the business of a single application center 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 set of centralized and dynamic configuration management settings is essential. Spring cloud provides ConfigServer to solve this problem.

2. SpringCloud Config schematic

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.

3. Spring cloud config is divided into server and client

(1) 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 the client with an access interface to obtain configuration information and encrypt / decrypt information.
(2) 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, and the configuration content can be easily managed and accessed through git client tools.

4. Function

(1) Centrally manage profiles.
(2) Different environments have different configurations. The dynamic session configuration is updated and deployed by environment, such as dev, test, prod, beta and release.
(3) During operation, the configuration is dynamically adjusted. There is no need to write a configuration file on the mechanism of each service deployment. The service will uniformly pull its own configuration information from the configuration center. When the configuration changes, the service can sense the configuration changes and apply the new configuration without restarting. (similar to observer mode)
(4) Expose the configuration information in the form of REST interface.

Config server configuration and test

1, Build a repository on github (this article takes building files on idea as an example)

2, Build cloud config center server3344 module
1. Introducing pom dependency

        <!--SpringCloud config Configuration center server dependency-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!--Eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--Import public entities or API rely on-->
        <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>

        <!--Hot deployment-->
        <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>

2. Write yml configuration file

# Service port number
server:
  port: 3344

# Service name
spring:
  application:
    name: cloud-config-center-server
  # Configuration center
  cloud:
    config:
      server:
        git:
          #Fill in your own github path
          uri: https://github.com/1914526816lhw/springcloud-config-repository.git
          #search for directory
          search-paths:
            - springcloud-config-repository
          # Account to connect to github (login account password)
          username: account number
          password: password
          # Set connection github timeout
          timeout: 60
          # Forced pulling
          force-pull: true



      # Read branch
      label: master


# Service registry
eureka:
  client:
    #Indicates that the receiver registers itself with EurekaServer. The default value is true
    register-with-eureka: true
    #Whether to retrieve the existing registration information from EurekaServer is true by default. It doesn't matter for a single node. The cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      #      defaultZone: http://localhost:7001/eureka # standalone
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka   #Cluster version
  instance:
    instance-id: config-center-server3344
    #The access path can display the IP address
    prefer-ip-address: true
    #The time interval between the eureka client sending heartbeat to the server, in seconds (30 seconds by default)
    lease-renewal-interval-in-seconds: 1
    #The maximum waiting time of eureka server after receiving the last heartbeat, in seconds (the default is 90 seconds). If it times out, the service will be deleted
    lease-expiration-duration-in-seconds: 2

3. Main startup class

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

4. Testing
Browser access: http://config3344.com:3344/master/config-dev.yml can normally obtain the contents of the config-dev.yml configuration file of the remote warehouse.

3, Config configure read rules

label: branch
application: service name
profile: environment (dev, test, prod)

1. / {label}/{application}-{profile}.yml (or. properties) [recommended], as shown in the figure:

2. / {application}-{profile}.yml (or. properties) if label is not configured in the configuration file. By default, the master branch is read. If the master branch does not exist, find another branch. If it does not exist, it returns null.

3. / {application}/{profile}/[{label}], reading the configuration file information returns json format, which can be parsed by yourself.

Config client configuration and testing

1. Build cloud config center client3355 module
2. Introducing pom dependency

        <!--SpringCloud config Configuration center client dependency-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--Eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--Import public entities or API rely on-->
        <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>

        <!--Hot deployment-->
        <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>

3. Write yml file configuration (here: bootstrap.yml)

bootstrap.yml concept

(1) application.yml is a user level resource configuration item.
(2) bootstrap.yml is system level with higher priority.

SpringCloud will create a Bootstrap Context as the parent context of the Application Context of Spring application. During initialization, the Bootstrap Context is responsible for loading configuration properties from external sources and parsing the configuration. The two contexts share an externally acquired Environment.
Bootstrap properties have high priority. By default, they will not be 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 very important to change the application.yml file under the Client module to the bootstrap.yml file. Because bootstrap.yml is loaded before application.yml, bootstrap.yml takes precedence over application.yml.

bootstrap.yml

server:
  port: 3355

spring:
  application:
    name: cloud-config-center-client
  cloud:
    # Config client configuration
    config:
      discovery:
        #Turn on service discovery
        enabled: true
        # Service id
        service-id: cloud-config-center-server
      label: master #Branch name
      name: config  #Profile name
      profile: dev  #Profile suffix name
      #      uri: http://localhost:3344 # configuration center server address
      uri: lb://cloud-config-center-server
      username: account number
      password: password


# Service registry
eureka:
  client:
    #Indicates that the receiver registers itself with EurekaServer. The default value is true
    register-with-eureka: true
    #Whether to retrieve the existing registration information from EurekaServer is true by default. It doesn't matter for a single node. The cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      #      defaultZone: http://localhost:7001/eureka # standalone
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka   #Cluster version
  instance:
    instance-id: config-center-client3355
    #The access path can display the IP address
    prefer-ip-address: true
    #The time interval between the eureka client sending heartbeat to the server, in seconds (30 seconds by default)
    lease-renewal-interval-in-seconds: 1
    #The maximum waiting time of eureka server after receiving the last heartbeat, in seconds (the default is 90 seconds). If it times out, the service will be deleted
    lease-expiration-duration-in-seconds: 2

4,controller

@RestController
public class ConfigClientController {

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

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

5. Testing: browser access http://localhost:3355/getConfigInfo Get with http://config3344.com:3344/master/config-dev.yml content, that is, the value in the remote configuration file, is as follows:

config:
  info: "master branch,springcloud-config-repository/config-dev.yml version=1"

Problem: after we modify the content of the remote warehouse configuration file, the server of the configuration center can obtain the configuration information of the heart by refreshing, but the client has no response after refreshing, and it is still the original configuration information. Except restart. So how to solve the problem of real-time update configuration? Next, the Config client is refreshed dynamically.

Config client dynamic refresh

1, Modify cloud config center client3355 module

1. Actor monitoring dependency with pom

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

2. Modify the yml file to expose the monitoring port

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

3. Add @ RefreshScope annotation to the controller business class

@RefreshScope
@RestController
public class ConfigClientController {

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

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

4. Testing

Theoretically, the content synchronization process is as follows: GitHub -- > 3344 -- > 3355

(1) Visit http://config3344.com:3344/master/config-dev.yml can normally access the contents of the configuration file.
(2) Direct refresh http://localhost:3355/getConfigInfo Without any response, the original value is obtained. Need to refresh 3355: curl - x POST through POST request“ http://localhost:3355/actuator/refresh ", the latest configuration content is updated when accessing again. Although it avoids restarting the client service. However, each service requires POST request refresh, which is still not ideal. How to deal with it? Then look down.

2, Broadcast (observer mode)
SpringCloud Bus message bus: to be updated

Topics: github config