How Does Nacos Register Services? Deep Dive into the Registration Flow
This article walks through Nacos's service registration mechanism, explaining how a client assembles a registration request, selects a random node in a cluster, routes the request, processes it on the server, and ensures eventual consistency using the Distro protocol.
Preface
Hello everyone, I am Su San.
In the previous article we explained how to use Nacos as a registry and configuration center.
This time we discuss the underlying principles of Nacos's registration service.
What steps does a registration request go through?
Knowledge Preview
Here is an overall flow diagram:
Cluster Environment: Topology of Nacos cluster.
Assemble Request: Client builds the registration request and calls Nacos.
Random Node: Client randomly selects a Nacos node for load balancing.
Routing Forward: Node checks if the request belongs to it; otherwise forwards.
Process Request: Node parses instance info and stores it in a custom memory structure.
Final Consistency: Uses Nacos's Distro protocol with delayed asynchronous tasks to sync data across nodes.
Async Retry: If registration fails, the client switches nodes and retries.
These points will be explained with diagrams and source code analysis.
Tip: This article uses Nacos version 2.0.4.
1. Source: Initiating Registration
1.1 Tips for Reading Source Code
Adding the @EnableDiscoveryClient annotation enables automatic service registration to Nacos.
Where exactly does the registration happen and what does the registration data look like?
First, look at the example folder in the source code. The App class contains the registration instance code.
You can also issue a curl command directly:
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.11&port=8080'Question: How does the @EnableDiscoveryClient annotation automatically register the service?
1.2 Registration Flowchart
Below is the code flow diagram:
We will debug this flow.
1.3 Assembling Instance Information
The core code assembles the instance information into an instance variable:
Debugging shows the instance data structure.
1.4 Assembling the Registration Request
The core method doRegisterService() builds a request containing the instance, namespace, serviceName, and groupName.
1.5 Remote Call
The requestToServer() method invokes RpcClient.request():
response = this.currentConnection.request(request, timeoutMills);This sends the request to a Nacos node; if in a cluster, it targets a specific node.
2. Cluster Environment: Prerequisite for Distribution
In a Nacos cluster, the client randomly selects a node to register.
2.1 Setting Up a Nacos Cluster
Local cluster with three Nacos instances (same IP, different ports):
192.168.10.197:8848
192.168.10.197:8858
192.168.10.197:8868Both Service A and Service B are configured with the cluster addresses:
spring.cloud.nacos.discovery.server-addr=192.168.10.197:8848,192.168.10.197:8858,192.168.10.197:8868Question: Does Service A register with all nodes or just one?
Answer: Before registration, a background thread randomly picks one address from the Nacos server list.
Design rationale: load balancing and high availability.
3. Random Node Selection
Client generates a random number to pick a node from the server list.
Relevant code:
// Get Nacos node info
serverInfo = recommendServer.get() == null ? nextRpcServer() : recommendServer.get();
// Connect to node
connectToServer = connectToServer(serverInfo);
// Assign connection
this.currentConnection = connectToServer;Method nextRpcServer() picks a random address:
// Random int in [0, server count)
currentIndex.set(new Random().nextInt(serverList.size()));
int index = currentIndex.incrementAndGet() % getServerList().size();
return getServerList().get(index);Summary: the client randomly selects an equal node for the call.
4. Routing Forwarding
4.1 Request and Forwarding Flow
Demo registration using curl:
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.11&port=8080'URL: /nacos/v1/ns/instance
Parameters: serviceName, ip, port.
If the receiving node is not responsible, it forwards the request based on a hash of the instance info.
4.2 Routing Logic Source
Entry point: DistroFilter.java in naming/src/main/java/com/alibaba/nacos/naming/web.
// Find target server
final String targetServer = distroMapper.mapSrv(distroTag);
int index = distroHash(responsibleTag) % servers.size();
// Hash the ip+port or service name
Math.abs(responsibleTag.hashCode() % Integer.MAX_VALUE);5. Processing the Request
Nacos v1 uses instanceController to handle registration.
Example curl to node 8858:
curl -X POST 'http://127.0.0.1:8858/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.11&port=8080'Core server code stores the instance in a synchronized block and triggers three actions:
Store instance in a ConcurrentHashMap.
Add a task to a BlockingQueue to push the updated list to clients via UDP.
Schedule a 1‑second delayed task to sync data to other Nacos nodes using the Distro protocol.
These steps ensure eventual consistency across the cluster.
6. Summary
This article demonstrated how a registration request triggers random node selection, routing forwarding, and storage of registration instances in Nacos, and introduced the Distro protocol for consistency.
Next article will dive into the Distro consistency protocol.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.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.
