Spring Cloud Ten: Introduction and Use of Configuration Center

One, configuration center

Why do you need a configuration center

For a single application, the configuration is written in the configuration file, there is no big problem. If you want to switch the environment, you can switch between different profiles (2 ways), but in microservices, there are more microservices. Hundreds and thousands of configurations require centralized management, management of configurations in different environments, dynamic adjustment of configuration parameters, and continuous service changes.

Introduction to Configuration Center

The distributed configuration center consists of 3 parts:

  1. Places to store configuration: git, svn, database, local files, etc.
  2. config server, read the configuration from 1.
  3. config client. It is the client consumption configuration of the config server.

Note: The configuration will not be updated by itself, and it is necessary to trigger the client before going to git to pull it. Or trigger to view the configuration on config-server, then go to git to pull it.

Second, use

Below we integrate Spring Cloud Config in the Spring Boot project, and use github as the configuration storage, mainly from the following two parts to demonstrate:

  1. Built out of Eureka's configuration center.
  2. The configuration center of Eureka is built.

Configuration file preparation:

We put the following four configuration files on github: Configuration center warehouse address

Insert picture description here

config-single-client-dev.yml

data:
  env: sinle-client-env
  user:
    username: bobo1
    password: 123

config-single-client-prod.yml

data:
  env: sinle-client-prod
  user:
    username: bobo2
    password: 1234

config-eureka-client-dev.yml

data:
  env: eureka-client-env
  user:
    username: bobo3
    password: 12345

config-eureka-client-prod.yml

data:
  env: eureka-client-prod
  user:
    username: bobo4
    password: 123456

1. Set up without Eureka's configuration center

The simplest configuration center is to start a service as a server, and then each service that needs to obtain configuration as a client to this server to obtain the configuration.

Create configuration center server

1. Create a new model, config-single-server, import web and config-server dependencies

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

2, placement application.yml

server:
  port: 7001
spring:
  application:
    name: config-single-server
  cloud:
    config:
      server:
        git:
		  # 配置文件仓库地址
          uri: https://github.com/zhaosongbobo/spring-cloud-config-test
          username: github帐号
          password: github密码
		  # 配置文件主干
          default-label: master
		  # 跳过ssl检查
          skip-ssl-validation: true
		  # 配置文件保存的本地机器的目录
          basedir: /home/bobo/config

3. Add @EnableConfigServer annotation to the startup class

@SpringBootApplication
@EnableConfigServer
public class ConfigSingleServerApplication {
    
    

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

}

4. Start config-single-server verification

Spring Cloud Config has its own set of access rules, and we can access it directly 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} is the application name, which corresponds to the configuration file, which is the spring.application.name value of the configuration file .
  • {profile} is the version of the configuration file. Our project has a development version, a test environment version, and a production environment version. Corresponding to the configuration file, it is distinguished by application-{profile}.yml, such as application-dev.yml, application- sit.yml, application-prod.yml.
  • {label} represents the git branch. The default is the master branch. If the project is distinguished by branch, it is possible to control access to different configuration files through different labels.

We follow the above rules to access the server we just started:

http://localhost:7001/config-single-client/dev/master

http://localhost:7001/config-single-client-dev.yml

http://localhost:7001/master/config-single-client-dev.yml

The output is as follows:

Insert picture description here

By visiting the above address, if the data can be returned normally, it means that everything is normal on the server side of the configuration center.

Create a configuration center client

The configuration center server is ready and the configuration data is ready. Next, we will use it in our project.

1. Create model, config-single-client, and import web, config dependency

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

2. Configure the bootstrap.yml and application.yml configuration files

bootstrap.yml

spring:
  application:
    name: config-single-client
  cloud:
    config:
      uri: http://localhost:7001
      profile: dev
      label: master
  profiles:
    active: dev

Note: Why use bootstrap configuration file here?

This is determined by the priority of loading the property file of spring boot. If you want to fetch the configuration file from the spring cloud config server before loading the properties, the spring cloud config related configuration needs to be loaded first, and the bootstrap.yaml Loading is before application.yaml, so the config client can only write the relevant configuration of config in bootstrap.properties.

application.yml

server:
  port: 7008

3. Read the content of the configuration file, generally obtained through @Value or @ConfigurationProperties

@Component
@Data
public class GitConfig {
    
    
    @Value("${data.env}")
    private String env;
    @Value("${data.user.username}")
    private String username;
    @Value("${data.user.password}")
    private String password;
}
@Component
@Data
@ConfigurationProperties(prefix = "data")
public class GitAutoRefreshConfig {
    
    
    
    private String env;
    private UserInfo user;
    
    @Data
    public static class UserInfo {
    
    
        private String username;
        private String password;
    }
}

4. GitController to test the configuration

@RestController
public class GitController {
    
    
    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoRefreshConfig gitAutoRefreshConfig;

    @GetMapping("/getInfo")
    public Object getInfo(){
    
    
        return gitConfig;
    }

    @GetMapping("/getAutoInfo")
    public Object getAutoInfo(){
    
    
        return gitAutoRefreshConfig;
    }
}

5. Results

Insert picture description here

Insert picture description here

2. Integrate Eureka's configuration center to build

If Eureka is used as a service registration discovery center in our system, Spring Cloud Config should also be registered on Eureka to facilitate the use of other service consumers, and multiple configuration center servers can be registered to achieve high availability.

Okay, let's integrate Spring Cloud Config to Eureka.

Create Eureka server

1. Create a new model, eureka-server, and configure pom dependencies

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

2, placement eureka, application.yml

spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url:
      defaultZone: http://euk-server1:8001/eureka/
  instance:
    hostname: euk-server1
server:
  port: 8001

3. Add @EnableEurekaServer annotation to the startup class

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    
    

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

}

Create the configuration center server and register it to EurekaServer

1. Create new model, config-eureka-server, add pom dependency

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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>

2. Configure eureka and config application.yml

server:
  port: 8002
spring:
  application:
    name: config-eureka-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/zhaosongbobo/spring-cloud-config-test
          username: github帐号
          password: github密码
          default-label: master
          skip-ssl-validation: true
          basedir: /home/bobo/config

eureka:
  instance:
    hostname: euk-server2
  client:
    service-url:
      defaultZone: http://euk-server1:8001/eureka

3. Add @EnableConfigServer and @EnableEurekaClient annotations to the startup class

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigEurekaServerApplication {
    
    

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

}

4. Start config-eureka-sever and verify that the configuration is successful

Insert picture description here

Create a configuration center client

The configuration of the client has relatively changed a bit. After joining Eureka, there is no need to directly deal with the configuration center server, but to access it through Eureka. In addition, pay attention to the application name of the client to be consistent with the name of the configuration file in github.

1. Create new model, config-eureka-client, add pom dependency

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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>

2. Configure bootstrap.yaml and application.yaml

bootstrap.yml

spring:
  application:
    name: config-eureka-client
  cloud:
    config:
      discovery:
        enabled: true
		# 指定配置中心服务端的server-id
        service-id: config-eureka-server
	  # 指定仓库主干
      label: master
	  # 指定版本
      profile: dev
eureka:
  client:
    service-url:
      defaultZone: http://euk-server1:8001/eureka/

application.yml

server:
  port: 8003

In addition to the configuration registered to Eureka, the configuration is to establish a relationship with the configuration center server.

The service-id is the application name of the server.

Note: Why use bootstrap configuration file here?

This is determined by the priority of loading the property file of spring boot. If you want to fetch the configuration file from the spring cloud config server before loading the properties, the spring cloud config related configuration needs to be loaded first, and the bootstrap.yaml Loading is before application.yaml, so the config client can only write the relevant configuration of config in bootstrap.properties.

3. Read the content of the configuration file, generally obtained through @Value or @ConfigurationProperties

Take it directly from the above example without any changes:

@Component
@Data
public class GitConfig {
    
    
    @Value("${data.env}")
    private String env;
    @Value("${data.user.username}")
    private String username;
    @Value("${data.user.password}")
    private String password;
}
@Component
@Data
@ConfigurationProperties(prefix = "data")
public class GitAutoRefreshConfig {
    
    
    
    private String env;
    private UserInfo user;
    
    @Data
    public static class UserInfo {
    
    
        private String username;
        private String password;
    }
}

4. GitController to test the configuration

@RestController
public class GitController {
    
    
    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoRefreshConfig gitAutoRefreshConfig;

    @GetMapping("/getInfo")
    public Object getInfo(){
    
    
        return gitConfig;
    }

    @GetMapping("/getAutoInfo")
    public Object getAutoInfo(){
    
    
        return gitAutoRefreshConfig;
    }
}

5. Startup class

@SpringBootApplication
@EnableDiscoveryClient
public class ConfigEurekaClientApplication {
    
    

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

}

6. Results

Insert picture description here

Three, manual refresh

The mechanism of Spring Cloud Config to load configuration content when the project starts has a defect that it will not automatically refresh after modifying the content of the configuration file. For example, in our project above, when the service has started, modify the content of the configuration file on github. At this time, refresh the page again. Sorry, it is the old configuration content, and the new content will not be refreshed actively.
However, you can't restart the service every time you modify the configuration. If that's the case, it's better not to use it. Wouldn't it be faster to use the local configuration file directly.

It provides a refresh mechanism, but we need to trigger it actively. That is @RefreshScope annotation combined with actuator, pay attention to the introduction of the spring-boot-starter-actuator package.

1. Add a dependency actuator to the pom dependency of config-eureka-client

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

2. Add actuator configuration in config client configuration

application.yml

server:
  port: 8003
management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

2. Add the @RefreshScope annotation to the class that needs to read the configuration. We use the configuration in the controller, so add it to the controller.

@RestController
@RefreshScope
public class GitController {
    
    
    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoRefreshConfig gitAutoRefreshConfig;

    @GetMapping("/getInfo")
    public Object getInfo(){
    
    
        return gitConfig;
    }

    @GetMapping("/getAutoInfo")
    public Object getAutoInfo(){
    
    
        return gitAutoRefreshConfig;
    }
}

Note that the above are all modifications made on the client side.

After that, restart the client. After restarting, we modify the configuration file config-eureka-client-dev.yml on github

original:

data:
  env: eureka-client-env
  user:
    username: bobo3
    password: 12345

After modification:

data:
  env: eureka-client-env
  user:
    username: bobo3修改111
    password: 12345

Refresh the page again, nothing happens.

Next, we send a POST request to the http://localhost:8003/actuator/refresh interface, using tools such as postman, this interface is used to trigger the loading of the new configuration, and the returned content is as follows:

Insert picture description here

After that, visit the RESTful interface again, http://localhost:8003/getAutoInfo

Insert picture description here

You can see that the data obtained by this interface is up to date, indicating that the refresh mechanism is working.

But when we visit http://localhost:8003/getInfo, we still get the old data, which is related to the implementation of the @Value annotation, so we should not use this method to load the configuration in the project.

Change to automatic refresh

Github provides a webhook method. When there is a code change, it will call the address we set to achieve the purpose we want to achieve.

1. Enter the github warehouse configuration page, select Webhooks, and click add webhook

Insert picture description here

2. Then fill in the address of the callback, which is the address mentioned above http://localhost:8003/actuator/refresh, but it must be ensured that this address is accessible by github. If it is an intranet, there is no way. This is just a demonstration. Generally, projects in the company will have their own code management tools, such as self-built gitlab. Gitlab also has the function of webhook, so that you can call the address of the intranet.

Insert picture description here

Four, automatic refresh

Use Spring Cloud Bus to automatically refresh multiple terminals:

Spring Cloud Bus 将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,Bus 就像一个扩展的 Spring Boot 应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。

—— Spring Cloud Bus 官方解释

No introduction here, you can refer to this article to achieve:

Spring Cloud Tutorial-Use Spring Cloud Bus to automatically refresh configuration changes

Five, write to the end

Here is such a problem when using the client to pull the configuration, here is the emphasis:

我用spring boot 2.4.1和spring cloud 2020.0.0-RC1版本去获取配置时获取不到。

把版本改为spring boot 2.3.4.RELEASE 和 spring cloud Hoxton.SR8版本获取配置正常

暂时不清楚为什么,可能新的版本有了变化,如果大家知道原因的话可以在评论区留言告知!!!

The examples used in this article have been uploaded to the code cloud:

click here to view

Guess you like

Origin blog.csdn.net/u013277209/article/details/111316799