Understanding Nacos Configuration Center: Pull Model, Long Polling, and Source Code Analysis
This article explains Nacos configuration center’s pull‑based data exchange, detailing the push vs pull models, long‑polling mechanism, core concepts like dataId, group, namespace, and provides in‑depth Java source‑code analysis of both client and server implementations.
Nacos, a popular service discovery and configuration management tool from Alibaba, is widely used in microservice architectures. This article examines how its configuration center works, focusing on whether configuration data is pushed from the server or pulled by the client.
The answer is that Nacos uses a client‑initiated pull model, implemented via long polling. The article first reviews the purpose of a configuration center: centralizing configuration, enabling dynamic updates without restarting applications, and avoiding the need to modify static yml or properties files across many services.
Two interaction models are described:
Push model : Server establishes a TCP long‑connection and pushes updates to the client immediately. It offers real‑time updates but can suffer from "dead" connections and requires heartbeat mechanisms like KeepAlive .
Pull model : Client periodically requests configuration (e.g., every 3 seconds). Simple but can cause latency and server load.
To combine real‑time benefits with simplicity, Nacos adopts a pull‑based long‑polling approach. The client sends a request that the server holds (up to ~30 seconds). If the configuration changes, the server responds immediately; otherwise, it replies after the timeout, and the client repeats the request.
Client‑side source analysis :
The Nacos client stores configuration metadata in a cacheMap (an AtomicReference<Map<String, CacheData>> ) where each key is a concatenated groupKey (dataId + group + tenant) and the value is a CacheData object. Key methods include:
private final AtomicReference
> cacheMap = new AtomicReference<>(new HashMap<>());Fetching configuration uses getConfig() (simple HTTP request) or getConfigAndSignListener() (adds a listener and triggers long polling). Listener registration updates the CacheData and notifies the server:
public void addTenantListenersWithContent(String dataId, String group, String content, List
listeners) throws NacosException { ... }Listeners are wrapped in ManagerListenerWrap , which stores the last MD5 hash to detect changes:
public void addListener(Listener listener) { ManagerListenerWrap wrap = (listener instanceof AbstractConfigChangeListener) ? new ManagerListenerWrap(listener, md5, content) : new ManagerListenerWrap(listener, md5); }When a configuration change is detected, the client’s safeNotifyListener method is invoked in a separate thread to deliver the new data via receiveConfigInfo() .
Server‑side source analysis :
The server exposes /v1/cs/configs/listener for long‑polling. It distinguishes long‑polling requests via the Long-Pulling-Timeout header and uses LongPollingService to handle them. The server reduces the client‑specified timeout by 500 ms to account for network latency.
When a client’s MD5 differs from the server’s, the server immediately returns the changed groupKey . Otherwise, it creates a ClientLongPolling task, schedules it for the remaining timeout (≈29.5 s), and stores it in an allSubs queue.
ConfigExecutor.executeLongPolling(new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag));The task holds an asyncContext so the servlet thread is released while the request is suspended. If a configuration change occurs (via publishConfig ), a ConfigDataChangeEvent is fired, and LongPollingService ’s DataChangeTask iterates over allSubs , finds matching long‑polling tasks, and completes them with asyncContext.complete() , instantly notifying the client.
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));Overall, the article demonstrates how Nacos achieves efficient configuration distribution using a pull‑based long‑polling mechanism, with detailed Java code snippets illustrating client caching, listener registration, and server‑side request suspension and notification.
Readers are encouraged to explore the source code further to deepen their understanding of Nacos’s design and implementation.
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.