How Nacos Implements Long‑Polling for Config Synchronization
This article explains the inner workings of Nacos' configuration center, detailing the client‑side long‑polling mechanism, the server‑side handling of listener requests, and the key classes and code paths that enable real‑time config updates in microservice environments.
After introducing Nacos basics and its role as a service registry, this article dives into one of the core principles of the Nacos configuration center: the long‑polling mechanism.
1. Client‑side long‑polling schedule
The process starts from NacosPropertySourceLocator.locate(), which creates a ConfigService instance. The creation flow follows NacosFactory.createConfigService() → ConfigFactory.createConfigService(), where reflection instantiates NacosConfigService. Inside NacosConfigService 's constructor, a ClientWorker is created, which starts a scheduled thread pool and launches the long‑polling task.
The long‑polling task is implemented in LongPollingRunnable.run(). It iterates over cacheMap (an AtomicReference<Map<String, CacheData>>) to check local config changes via checkLocalConfig(). If changes are detected, it triggers notifications. Otherwise, it calls checkUpdateDataIds(), which ultimately invokes checkUpdateConfigStr() and sends a long‑polling HTTP request to /v1/cs/configs/listener using MetricsHttpAgent.httpPost(). The request includes a long timeout (default 30 s). When the server reports changed dataId, getServerConfig() fetches the new content via MetricsHttpAgent.httpGet() from /v1/cs/configs, and the snapshot is saved locally.
1.1 Instantiating NacosConfigService via reflection
The factory method uses reflection to create the NacosConfigService object.
1.2 Starting the scheduled long‑polling task
ClientWorker.ClientWorker()creates two thread pools and schedules the periodic check.
1.3 Checking configuration changes
LongPollingRunnable.run()splits tasks based on taskId, checks local files under ${user}\nacos\config\, and, if needed, fetches updated configurations from the server.
public static ConfigService createConfigService(Properties properties) throws NacosException {
//【断点步入】创建 ConfigService
return ConfigFactory.createConfigService(properties);
}2. Server‑side long‑polling schedule
The Nacos server receives listener requests via ConfigController.listener(). The request is processed by ConfigServletInner.doPollingConfig(), which delegates to LongPollingService.addLongPollingClient(). This method wraps the client request into a ClientPolling object and submits it to a scheduler.
The core execution occurs in ClientLongPolling.run(), which holds the request for up to 30 s. If no configuration change occurs, the response is delayed; otherwise, the server returns the changed dataId, group, and tenant immediately.
When a configuration change is detected on the server, a LocalDataChangeEvent is published. Prior to Nacos 1.3.1, LongPollingService.onEvent() handled the event; from 1.3.2 onward, a Subscriber.onEvent() processes it, triggering a DataChangeTask that fetches the updated config and sends the response back to the client.
3. Summary of the source code structure
The following diagram outlines the main call chain on both client and server sides:
NacosPropertySourceLocator.locate() – initializes ConfigService NacosConfigService.NacosConfigService() – constructor sets up workers
Executors.newScheduledThreadPool() – creates thread pools
ClientWorker.checkConfigInfo() – periodic check for changes
ClientWorker.checkLocalConfig() – local file comparison
ClientWorker.checkUpdateDataIds() – server‑side change detection
ClientWorker.getServerConfig() – fetches updated config
MetricsHttpAgent.httpPost() – long‑polling request to /listener MetricsHttpAgent.httpGet() – fetches config from /configs LongPollingRunnable.run() – runs client‑side polling thread
ConfigController.listener() – server receives request
LongPollingService.addLongPollingClient() – registers client polling
ClientLongPolling.run() – server‑side polling execution
DataChangeTask.run() – processes config change events
These components together realize Nacos' efficient long‑polling mechanism, ensuring that configuration updates are propagated to clients with minimal latency while avoiding excessive polling traffic.
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.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.
