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<CacheData> 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.
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.
