Alibaba microservice component Nacos configuration center

01 actual combat of Nacos configuration center

Introduce dependency

         <!--nacos Configuration center-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

The priority of the configuration file is from high to low

# ${spring.application.name}-${profile}.${file-extension:properties}
#${spring.application.name}.${file-extension:properties}
#${spring.application.name}
#extensionConfigs    nacos.yml
#sharedConfigs multiple microservices public configuration redis
@RestController
@RefreshScope // This annotation can sense changes in value
public class TestController {

    @Value("${common.age}")
    private String age;

    @GetMapping("/common")
    public String hello() {
        return age;
    }

}

In bootstrap Configure in the properties file. You can configure profile / namespace / group / dataId (directly specify the file name). The dataId can also be shared sharedConfigs or independent extensionConfigs

spring.application.name=nacos-config
# Configuration center address
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# Close configuration center
#spring.cloud.nacos.config.enabled = false

# Configuration method of file extension with dataid yaml
# `${spring.application.name}.${file-extension:properties}`
spring.cloud.nacos.config.file-extension=yaml
#Profile granularity configuration ` ${spring. Application. Name} - ${profile}$ {file-extension:properties}`
# nacos-config-prod.yaml
spring.profiles.active=prod

#Customize the configuration of the namespace
spring.cloud.nacos.config.namespace=39e1e969-15f9-46d2-832d-fa052da55377

# Custom Group configuration
spring.cloud.nacos.config.group=DEFAULT_GROUP

# Custom Data Id configuration
#Common configurations of different projects support shared dataid redis
spring.cloud.nacos.config.sharedConfigs[0].data-id= common.yaml
spring.cloud.nacos.config.sharedConfigs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.sharedConfigs[0].refresh=true

# config external configuration
# Supports the configuration of one application with multiple dataids yml  mybatis. yml
spring.cloud.nacos.config.extensionConfigs[0].data-id=nacos.yaml
spring.cloud.nacos.config.extensionConfigs[0].group=REFRESH_GROUP
spring.cloud.nacos.config.extensionConfigs[0].refresh=true

Spring boot and nacos integration

<dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-config-spring-boot-actuator</artifactId>
            <version>${nacos-config-spring-boot.version}</version>
        </dependency>
application. That's enough for the properties configuration file, Nacos config. server-addr=127.0.0.1:8848
@SpringBootApplication
// Configure which dataId to use as the data source
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfigApplication {

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

@Controller
@RequestMapping("config")
public class ConfigController {
    // Get the value of this configuration
    @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
    private boolean useLocalCache;

    @RequestMapping(value = "/get", method = GET)
    @ResponseBody
    public boolean get() {
        return useLocalCache;
    }
}

02 analysis of Nacos configuration center architecture

 

03 source code analysis of Nacos config client

Entry: interface core method

What is the priority of multiple configurations

springboot load attribute configuration: org springframework. boot. env. The propertysourceloader interface has two implementation classes

Take the load method of an implementation class as its entry org springframework. boot. env. PropertiesPropertySourceLoader#load

During the startup process, the run method of SpringApplication is also followed, and the ApplicationEnvironmentPreparedEvent environment preparation event is released. The org \ springframework \ cloud \ bootstrap \ bootstrap applicationlistener listener is triggered, and the springboot method is called back during the process. Configurableenvironment environment = this prepareEnvironment(listeners, applicationArguments); The event is also passed to the spring boot listener ConfigFileApplicationListener, which will load all configuration files. In the process, the PropertiesPropertySourceLoader#load method loads bootstrap Properties, and then load application properties...

04 how does the client get the configuration from the configuration center

The main method to obtain the configuration is the getConfig method of the NacosConfigService class. Usually, this method directly obtains the configuration value from the local file. If the local file does not exist or the content is empty, then pull the configuration from the remote through the HTTP GET method and save it to the local snapshot. When obtaining remote configuration through HTTP , Nacos , provides two fusing strategies, one is the timeout time, the other is the maximum number of retries, and the default is three retries.

05 how does the Client perceive the change of configuration in the configuration center

After all configuration files are loaded, a corresponding listener will be added to all dataid s. A thread in the background will regularly check the configuration file information. After finding that the file md5 has changed, the listener's method will be triggered. RefreshEvent will be published inside the method. This RefreshEventListener will trigger the refresh of ContextRefresher to refresh the environment, When replacing the previous environment, the bean modified by the annotation @ RefreshScope will be stored in a container, and the old bean will be remove d and replaced with a new bean

06 source code analysis of Nacos config server

public class ConfigServerDemo {

    public static void main(String[] args) throws NacosException, InterruptedException {
        String serverAddr = "localhost:8848";
        String dataId = "nacos-config-demo.yaml";
        String group = "DEFAULT_GROUP";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        
        //Get configuration center service
        ConfigService configService = NacosFactory.createConfigService(properties);
        
        //Pull configuration from configuration center
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        //Register listener
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("Perceived configuration change:" + configInfo);
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });

        //Publish configuration send properties format
        configService.publishConfig(dataId,group,"common.age=30", ConfigType.PROPERTIES.getType());

        Thread.sleep(3000);
        //Pull configuration from configuration center
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        
        Thread.sleep(Integer.MAX_VALUE);

    }
}

07 how do other nodes synchronize configuration data under the cluster architecture

When the server starts, it will rely on the # init # method of # DumpService # to load # configuration from the database and store it on the local disk, and cache some important meta information, such as # MD5 # value in memory. According to the last heartbeat time saved in the heartbeat file, the server will determine whether to dump the full configuration data or part of the incremental configuration data from the database (if the last heartbeat interval of the machine is less than 6 h).

Of course, first empty the disk cache, and then fetch 1000 configurations each time according to the primary key ID and brush them into the disk and memory. Incremental {dump} is to retrieve the new configurations (including updated and deleted) in the last six hours. First refresh the memory and files according to this batch of data, and then compare the database according to the total amount of all data in the memory. If there are changes, synchronize again. Compared with the total amount of} dump}, it will reduce a certain number of database} IO} and disk} IO} times.

If you want to change the mysql configuration and update it to the client immediately, you need to write a listener to listen for changes and publish a ConfigDataChangeEvent event. Otherwise, the server will not be aware of it without restarting.

Keywords: Java Distribution Nacos

Added by sabien on Tue, 18 Jan 2022 22:56:54 +0200