How Nacos Uses Long‑Polling to Detect Config Changes
This article explains the inner workings of Nacos Config Center’s long‑polling mechanism, covering client‑side initialization, the scheduling of ConfigService, how ConfigFactory creates NacosConfigService via reflection, the periodic checks performed by ClientWorker, and the server‑side handling of long‑polling requests that deliver configuration updates.
Today we introduce one of Nacos Config Center’s core principles: the long‑polling mechanism used for dynamic configuration listening.
For clarity, the Nacos console and registration center are referred to as the Nacos server, while the business services we write are called Nacos clients.
1. Client‑side long‑polling scheduling
The process starts from ConfigService, the class provided by the Nacos client for basic configuration operations. The entry point is NacosPropertySourceLocator.locate(), which creates a ConfigService instance.
1.1 Instantiating NacosConfigService via reflection
The client creates the long‑polling task in NacosFactory.createConfigService(), which builds the ConfigService object. Inside this method, ConfigFactory.createConfigService(properties) is called, using reflection to instantiate NacosConfigService.
1.2 Initializing the long‑polling task
In the constructor NacosConfigService.NacosConfigService(), several components are set up:
HttpAgent initialization : MetricsHttpAgent and ServerHttpAgent are created to handle HTTP communication.
ClientWorker initialization : ClientWorker.ClientWorker() creates two scheduled thread pools and starts a periodic task that runs every 10 seconds to check for configuration changes.
1.2.1 Checking configuration changes
The method ClientWorker.checkConfigInfo() iterates over the cacheMap (an AtomicReference<Map<String, CacheData>>) and, for each entry, calls checkLocalConfig() to compare the local file ( ${user}\nacos\config\) with the cached version.
1.3 Long‑polling execution
The core logic resides in LongPollingRunnable.run():
Split the cacheMap into tasks based on taskId.
Call checkLocalConfig() to detect local changes.
Invoke checkUpdateDataIds() (which uses MetricsHttpAgent.httpPost() to call /v1/cs/configs/listener) to see if the server reports changed Data ID, Group, or Tenant.
If changes are detected, getServerConfig() (via MetricsHttpAgent.httpGet() to /v1/cs/configs) fetches the new configuration and updates the CacheData object.
public static ConfigService createConfigService(Properties properties) throws NacosException {<br/> //【Breakpoint】create ConfigService<br/> return ConfigFactory.createConfigService(properties);<br/>} public void run() {<br/> List<CacheData> cacheDatas = new ArrayList();<br/> // iterate CacheData, check local config<br/> for (CacheData cacheData : ClientWorker.this.cacheMap.get().values()) {<br/> if (cacheData.getTaskId() == this.taskId) {<br/> cacheDatas.add(cacheData);<br/> try {<br/> ClientWorker.this.checkLocalConfig(cacheData);<br/> if (cacheData.isUseLocalConfigInfo()) {<br/> cacheData.checkListenerMd5();<br/> }<br/> } catch (Exception e) {<br/> ClientWorker.LOGGER.error(Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
