Nacos configuration center source code | JD Logistics technical team

client

Entrance

Found in the jar file that introduces the maven dependency of the configuration center , find the NacosConfigBootstrapConfiguration configuration class in the configuration file. This class is the entry class of the nacos configuration center, and three beans are registered in the class.spring-cloud-starter-alibaba-nacos-config-2.2.5.RELEASE.jar!/META-INF/spring.factories





NacosConfigProperties: Property configuration class, corresponding to the properties prefixed by spring.cloud.nacos.config in the configuration file.

NacosConfigManager: manages NacosConfigProperties and ConfigService.

NacosPropertySourceLocator: Load configuration center configuration information.

NacosConfigManager

In the NacosConfigManager constructor, the createConfigService method is called, which calls the constructor of the ConfigService implementation class through the factory class to create a ConfigService instance.





In the constructor of the ConfigService implementation class NacosConfigService, this.agent = new MetricsHttpAgent(new ServerHttpAgent(properties)); will be initialized. This agent is an agent used to send requests to the server.



 

The NacosRestTemplate attribute in the ServerHttpAgent class is a tool class for sending remote calls. It will call the HttpMethod.GET method to call the server rest request.



In the method returning to NacosConfigService#NacosConfigService this.worker = new ClientWorker(this.agent, this.configFilterChainManager, properties); This property is the client worker thread class, and there are two thread pools inside the class:

1. The thread pool with only one thread is used to perform scheduled tasks. The checkConfigInfo(); method is executed every 10ms. The cacheData instances to be polled are obtained for each batch of 3000 configuration items, and are packaged into a LongPollingTask submission. Enter the second thread pool executorService for processing.this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory()





2. A thread pool with the number of threads equal to the number of processors is used to execute ClientWorker.LongPollingRunnable#LongPollingRunnable#run. The configuration that needs to be refreshed is cached in the cacheMap. Divide the number in the cacheMap into a group of 3000 and create a LongPollingRunnable for monitoring. Configuration update, call checkLocalConfig(cacheData) in the LongPollingRunnable#run method; check the local configuration and fault-tolerant processing; call checkUpdateDataIds(cacheDatas, inInitializingCacheList); The method is to send a long connection timeout event to the nacos server for 30s and return the updated dataids; call getServerConfig(dataId, group, tenant, 3000L); The method is to call the server configuration center interface to obtain the configuration attributes based on the returned dataids, and update the local snapshot; call checkListenerMd5(); to add the changed configuration Monitoring processing; finally continue to call executorService.execute(this); method polling processing.







CacheData#checkListenerMd5





In the listener.receiveConfigInfo(contentTmp); method, the AbstractSharedListener#receiveConfigInfo method will be called and the RefreshEvent event will be published.





The corresponding event listener is: RefreshEventListener, implemented by Spring Cloud. In this listener, the configuration is updated and the configuration marked with @RefreshScope is refreshed in the container. Two events are listened to in the onApplicationEvent method, ApplicationReadyEvent (spring boot event, indicating that the application should Initialization completed), RefreshEvent.





RefreshEvent: this.handle((RefreshEvent)event); handles this event to refresh the configuration marked with @RefreshScope annotation in the container, org.springframework.cloud.context.refresh.ContextRefresher#refresh





refreshEnvironment(); extract(this.context.getEnvironment().getPropertySources()) to extract variables other than system variables; addConfigFilesToEnvironment(); put the parameters in the original environment into a new spring context container and re- Load and close the new container after completion. Here is the new value of the parameter;





changes(before,extract(this.context.getEnvironment().getPropertySources())) Gets the new parameter value and compares it with the previous one to find the changed parameter value.



this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys)); Publish environment change event with changed parameter values.

Return to the ContextRefresher#refresh method and look at this.scope.refreshAll(); to refresh the bean annotated with @RefreshScope.





super.destroy(); method, clear the cache in the scope, and a new instance will be obtained from the BeanFactory next time and the new configuration will be used.

this.context.publishEvent(new RefreshScopeRefreshedEvent()); method publishes events.

Server

DumpService

The DumpService class is an abstract class responsible for querying configurations from storage and saving them to disk. It has two subclasses, EmbeddedDumpService embedded storage (DERBY) and ExternalDumpService extended data storage.



The @PostConstruct annotation is on the init method of the ExternalDumpService implementation class. During the process of spring building the bean, the initialization method with @PostConstruct will be executed.

Call the method of the abstract parent class DumpService#dumpOperate, and call the dumpConfigInfo method. The dumpConfigInfo method will determine whether to update in full or in addition.



If isAllDump is true, a full update will be performed. It will be judged whether there is a quick update configuration, whether there is a heartbeat check file, and whether the last check time is less than 6 hours. If the above judgments are met, a full update will not be performed. Otherwise, a full update will be performed.



dumpAllProcessor.process(new DumpAllTask()); Query all configInfo configuration information in the database and write it to the server-side disk cache.



persistService.findConfigMaxId(); Query the largest primary key in the database for paging processing.



persistService.findAllConfigInfoFragment(lastMaxId, PAGE_SIZE); Query data from the database in pages, each time querying 1000 items.





ConfigCacheService.dump(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getContent(), cf.getLastModified(),cf.getType()); Write to disk



save to file



updateMd5(groupKey, md5, lastModifiedTs); Cache the MD5 of the configuration information into memory and publish the LocalDataChangeEvent event.



The event listener will be called in NotifyCenter.registerSubscriber.



Get configuration

HttpMethod.GET /nacos/v1/cs/configs Get the server configuration interface, ConfigController#getConfig.



inner.doGetConfig(request, response, dataId, group, tenant, tag, clientIp); is called in getConfig;

In the doGetConfig method, the DiskUtil.targetBetaFile(dataId, group, tenant); method will be called to obtain it from the local disk, not from mysql. If the mysql data is modified directly, it will not take effect. The ConfigDataChangeEvent event needs to be published to trigger the update.



Listening configuration

HttpMethod.POST request calls /nacos/v1/cs/configs/listener polling interface to call long connection.



longPollingService.addLongPollingClient(request, response, clientMd5Map, probeRequestSize); Long connection polling processing.



SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500); The maximum processing time is 29.5s. You need to reserve 0.5s to respond to the client to avoid timeout.



MD5Util.compareMd5(req, rsp, clientMd5Map); Compares whether the client's md5 is consistent with the current server's. Inconsistency is returned to changedGroups.



If there is inconsistent data, respond directly to generateResponse(req, rsp, changedGroups);



The thread pool executes the long connection task ConfigExecutor.executeLongPolling.



LongPollingService.ClientLongPolling#run long polling.



ConfigExecutor.scheduleLongPolling delays execution for 29.5s



Delayed execution first deletes its own tasks in the queue allSubs.remove(ClientLongPolling.this);



allSubs.add(this); add to queue



inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());



MD5Util.compareMd5(request, response, clientMd5Map); Compare with the current configuration and return the changed configuration

nacos management side change configuration

HttpMethod.POST /nacos/v1/cs/configs



persistService.insertOrUpdate(srcIp, srcUser, configInfo, time, configAdvanceInfo, true); Persistence information to the database.









Go back to ConfigController#publishConfig and look at the ConfigChangePublisher.notifyConfigChange method to trigger the ConfigDataChangeEvent event.





ConfigDataChangeEvent event listener.



ConfigExecutor.executeAsyncNotify(new AsyncTask(nacosAsyncRestTemplate, queue)); Synchronize other nodes.



In addition, LongPollingService subscribed to the LocalDataChangeEvent event when it was initialized and will also listen to it.



ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps));

Take a look at LongPollingService.DataChangeTask#run, push mode, traverse allSubs and respond to the client with the changed key. clientSub.sendResponse(Arrays.asList(groupKey));

 

Author: JD Logistics Zhang Shixin

Source: JD Cloud Developer Community Ziyuanqishuo Tech Please indicate the source when reprinting

IntelliJ IDEA 2023.3 & JetBrains Family Bucket annual major version update new concept "defensive programming": make yourself a stable job GitHub.com runs more than 1,200 MySQL hosts, how to seamlessly upgrade to 8.0? Stephen Chow's Web3 team will launch an independent App next month. Will Firefox be eliminated? Visual Studio Code 1.85 released, floating window Yu Chengdong: Huawei will launch disruptive products next year and rewrite the history of the industry. The US CISA recommends abandoning C/C++ to eliminate memory security vulnerabilities. TIOBE December: C# is expected to become the programming language of the year. A paper written by Lei Jun 30 years ago : "Principle and Design of Computer Virus Determination Expert System"
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/10320447
Recommended