Let the Spring Boot configuration "move"

Keywords: Spring Spring Boot mvc

preface

For microservices, configuration localization is a big disadvantage. It is impossible to restart the service every time you need to change the configuration. Therefore, the final solution is to externalize the configuration and host it on one platform, so that multiple modifications can take effect at one time without restarting the service.

However, for the Spring Boot project of single application, dynamic refresh is obviously a little redundant. Anyway, it's just a service. Why don't you just restart it?

However, dynamic refresh must be used in some special scenarios, as follows:

  1. Add data source: when connecting to a third-party platform, you cannot restart the service every time you add a data source

  2. Fixed docking: there are a large number of fixed docking methods, but one of the fixed code segments is different, such as different fields in the provided view, different fields in the interface service, etc.

Of course, each company has different solutions for the two scenarios listed above, which will not be discussed here.

What are the mainstream solutions under microservices?

There are three main ways of dynamic configuration center under microservice, as shown in the following figure:

The three configuration center schemes in the figure above can be said to have the highest utilization rate in the enterprise, namely:

  1. Nacos: Alibaba's recent open source project, this guy is very awesome. One killed Eureka (stop watch) and Config+Bus, which can be used as both a configuration center and a registration center, and has its own independent management platform, which can be said to be the most mainstream one now.

  2. Config+Bus: the microservice configuration center in use in the early days can manage the microservice configuration file based on GitHub. This is also used by many enterprises now, but they need to deploy a microservice independently, which is much inferior to Nacos.

  3. Apollo: Ctrip's Open Source Project Apollo is also used by many enterprises. Chen doesn't know much. If you are interested, you can study it in depth.

How many schemes are applicable to Spring Boot?

In fact, the above three can be adapted in the Spring Boot project, but it is a little heavy as a single application. The following author briefly introduces two available schemes.

Spring Boot+Nacos (not recommended)

It has to be said that Alibaba is really ambitious. What Alibaba wants to do is actually a micro service ecosystem. Nacos can not only be used as the configuration and registration center of Spring Cloud, but also adapt to Dubbo and K8s. The official documents have made a detailed introduction on how to adapt. The author will not introduce it in detail here, as shown in the following figure:

Of course, Nacos is also applicable to Spring and Spring Boot projects.

How to use it? Here, the author only provides the following ideas and does not do too much in-depth research. This article will be introduced in detail in the author's next column, advanced Spring Cloud:

  1. Download the corresponding version of Nacos, start the project, and visit http://localhost:8848 Enter the management interface of Nacos;

  2. The configuration of Nacos introduced by Spring Boot project depends on Nacos config Spring Boot starter to configure the address of Nacos management center.

  3. @NacosPropertySource and @ NacosValue are combined.

  • @NacosPropertySource: Specifies the dataId of the configuration center and whether to refresh automatically

  • @NacosValue replaces the @ Value annotation to complete the automatic assembly of attributes

  1. If the company's project is managed in the background, you can directly call the API opened by Nacos to modify the value of the corresponding configuration (instead of the manual operation of the Nacos management interface). The address of the API is: https://nacos.io/zh-cn/docs/open-api.html

Although this scheme can realize the dynamic refresh of configuration, it is also necessary to integrate Nacos and start a Nacos service. It is completely overqualified and is not recommended in actual projects.

Spring boot + config + actor (recommended)

This scheme actually uses the Config configuration center, but it is not as heavy as Nacos. It is fully applicable to the SpringBoot project of single application. Only a small part of changes are needed to achieve the effect.

Scheme I (not recommended)

  1. Add the dependency of Config as follows:

<!-- springCloud Dependence of-->
<dependencyManagement>
    <dependencies>
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
    </dependencies>
</dependencyManagement>

<!-- config Dependence of-->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

  <!-- actuator Dependence of-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  1. The endpoint of Spring Boot is exposed in the configuration file, as follows:

management.endpoints.web.exposure.include=*
  1. Three new attribute configurations are added in the configuration file:

config.version=22
config.app.name=dynamic-project
config.platform=mysql
  1. Combine the @ RefreshScope annotation to dynamically refresh and write a Controller as follows:

@RestController
//@RefreshScope the annotation must be marked, otherwise the dynamic update cannot be completed
@RefreshScope
public class DynamicConfigController {
    @Value("${config.version}")
    private String version;

    @Value("${config.app.name}")
    private String appName;

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


    @GetMapping("/show/version")
    public String test(){
        return "version="+version+"-appName="+appName+"-platform="+platform;
    }
  1. Start the project test and visit the browser http://localhost:8080/show/version , the returned information is as follows:

  1. Modify the configuration file in the target directory as follows:

config.version=33
config.app.name=dynamic-project
config.platform=ORACLE
  1. POST request http://localhost:8080/actuator/refresh Interface, manually refresh the configuration (required, otherwise it cannot be refreshed automatically)

  2. Browser input again http://localhost:8080/show/version The results are as follows:

You can see that the configuration has been modified automatically. End.

Scheme II (recommended)

What do you think of scheme 1? Is it a little chicken ribs

First question: why call a manual refresh?

Second question: can I only change it manually in the configuration file? What if you want to change the background management system?

To solve the above two problems, we still need to look at the source code of Config. The key part of the code is in the org. Springframework. Cloud. Context. Refresh. Contextrefresh #refresh() method, as shown in the following figure:

So you only need to call the following ContextRefresher#refresh() (asynchronously, avoid blocking wait) after modifying the attribute.

To facilitate testing, we manually write a refresh interface, as follows:

@GetMapping("/show/refresh")
    public String refresh(){
        //Modify properties in the configuration file
        HashMap<String, Object> map = new HashMap<>();
        map.put("config.version",99);
        map.put("config.app.name","appName");
        map.put("config.platform","ORACLE");
        MapPropertySource propertySource=new MapPropertySource("dynamic",map);
        //Set the modified configuration to the environment
        environment.getPropertySources().addFirst(propertySource);
        //Call the refresh method asynchronously to avoid blocking and waiting for no response
        new Thread(() -> contextRefresher.refresh()).start();
        return "success";
    }

In the above code, the author only manually sets the value in the configuration file. In the actual project, the configuration refresh can be read from the database through persistence.

Let's test, start the project and visit http://localhost:8080/show/version , it is found that it is the value previously configured in application.properties, as shown in the following figure:

Call the refresh interface: http://localhost:8080/show/refresh Reset the attribute value;

Call again http://localhost:8080/show/version Check whether the following configuration has been modified, as shown in the following figure:

It can be seen from the above figure that the configuration has indeed been modified to achieve the effect of dynamic refresh.

summary

This paper introduces the configuration center of micro services to the simple configuration center built by Spring Boot, and introduces several feasible schemes in detail. The author strongly recommends the last scheme, the simplified version of Config, which is fully suitable for single applications.

Posted by CiPH on Tue, 23 Nov 2021 05:58:30 -0800