Understanding Nacos Long‑Polling Mechanism in Spring Cloud Alibaba
This article explains the internal long‑polling mechanism of Nacos configuration center used in Spring Cloud Alibaba, covering client‑side initialization, thread‑pool scheduling, request handling, server‑side processing, event listening, and code snippets that illustrate how configuration changes are detected and propagated.
Introduction – The author announces the completion of a video tutorial series on Spring Cloud Alibaba, which includes topics such as Alibaba middleware, OAuth2 microservice authentication, gray release, and distributed transactions.
1. Client‑Side Long‑Polling Scheduling
The journey starts from NacosPropertySourceLocator.locate() , which creates a ConfigService instance. The long‑polling task is launched inside NacosFactory.createConfigService() and subsequently in ConfigFactory.createConfigService() via reflection.
Inside NacosConfigService constructor, several components are initialized, including the HTTP agents and the ClientWorker thread pool.
1.1 Instantiating NacosConfigService via Reflection
The method NacosFactory.createConfigService() simply delegates to ConfigFactory.createConfigService() , which uses reflection to create the concrete NacosConfigService object.
1.2 Starting the Long‑Polling Task in NacosConfigService
The constructor of NacosConfigService sets up the necessary properties for the remote polling task.
1.2.1 Initializing HttpAgent
The design of MetricsHttpAgent and ServerHttpAgent is shown in the accompanying diagrams.
1.2.2 Initializing ClientWorker
ClientWorker.ClientWorker() creates two scheduled thread pools and starts a periodic task that checks configuration changes every 10 seconds via ClientWorker.checkConfigInfo() . The internal cache map ( AtomicReference<Map<String, CacheData>> ) stores listeners keyed by dataId/group/tenant . Long‑polling tasks are split into LongPollingRunnable instances, each handling up to 3000 listeners.
1.3 Checking Configuration Changes
The method LongPollingRunnable.run() iterates over cached data, calls checkLocalConfig() to compare local files, and then invokes checkUpdateDataIds() to query the server for changes. If a change is detected, getServerConfig() fetches the new content and triggers listener notifications.
public void run() {
List
cacheDatas = new ArrayList();
// ... iterate cache, check local config, request updates ...
// on change, fetch new config and notify listeners
}1.3.1 checkUpdateDataIds()
This method ultimately calls checkUpdateConfigStr() , which sends a long‑polling HTTP POST to /v1/cs/configs/listener using MetricsHttpAgent.httpPost() . The request includes a long timeout (default 30 s). A successful response contains the changed dataId , group , and tenant .
1.3.2 getServerConfig()
After receiving the change notification, ClientWorker.getServerConfig() performs an HTTP GET to /v1/cs/configs via MetricsHttpAgent.httpGet() and saves the snapshot locally using LocalConfigInfoProcessor.saveSnapshot() .
2. Server‑Side Long‑Polling Scheduling
2.1 Receiving Requests – ConfigController.listener()
The server side implements the /listener endpoint in ConfigController . The request is processed by ConfigServletInner.doPollingConfig() , which delegates to LongPollingService.addLongPollingClient() .
2.2 Executing Long‑Polling – LongPollingService
The core logic creates a ClientLongPolling object and schedules it with a delay (approximately 29.5 s). If no configuration change occurs, the server holds the request until the timeout expires.
2.3 ClientLongPolling.run()
This method keeps the connection alive for up to 30 s, returning a response only when a change is detected, thereby achieving efficient long‑polling.
2.4 Listening to Configuration Change Events
2.4.1 LocalDataChangeEvent
When a configuration is modified on the Nacos server, a LocalDataChangeEvent is published. Prior to Nacos 1.3.1, LongPollingService.onEvent() handled the event; after 1.3.1, a Subscriber listens via onEvent() and dispatches a DataChangeTask to a thread pool.
2.4.2 DataChangeTask.run()
The task retrieves the updated configuration based on the groupKey and sends the result back to the client.
3. Summary of Source Code Structure
3.1 Client‑Side Flow
NacosPropertySourceLocator.locate() – initializes ConfigService
NacosConfigService.NacosConfigService() – constructor
Executors.newScheduledThreadPool() – creates thread pools
ClientWorker.checkConfigInfo() – periodic change check
ClientWorker.checkLocalConfig() – local file comparison
ClientWorker.checkUpdateDataIds() – server change detection
ClientWorker.getServerConfig() – fetches updated config
MetricsHttpAgent.httpPost() – long‑polling request
MetricsHttpAgent.httpGet() – config retrieval
LongPollingRunnable.run() – executes polling task
3.2 Server‑Side Flow
ConfigController.listener() – receives request
LongPollingService.addLongPollingClient() – registers client
ClientLongPolling.run() – implements timeout logic
ConfigExecutor.scheduleLongPolling() – schedules task
MD5Util.compareMd5() – change detection
LongPollingService.sendResponse() – returns result
Conclusion
The article provides a detailed walkthrough of Nacos long‑polling, complete with diagrams and source code snippets, helping developers understand how configuration changes are detected and propagated in a Spring Cloud Alibaba environment.
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.