Backend Development 19 min read

Deep Dive into Nacos Service Registry: Architecture, Registration, and Discovery Mechanisms

This article provides a comprehensive technical walkthrough of Nacos as a service registry, covering its core features, architecture components, the underlying registration and health‑check processes, source‑code analysis of Spring Cloud integration, and the detailed service‑discovery workflow.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Deep Dive into Nacos Service Registry: Architecture, Registration, and Discovery Mechanisms

This article introduces Nacos, a unified configuration, service registration, and discovery solution for micro‑service architectures. It outlines the main capabilities of Nacos, including service address management, registration, dynamic health monitoring, dynamic configuration, DNS‑based service discovery, weighted routing, and metadata management.

Architecture Overview

The Nacos system consists of several modules: Provider APP (service provider), Consumer APP (service consumer), Name Server (high‑availability routing via Virtual IP or DNS), Nacos Server (the core server), and the Nacos Console. The server includes OpenAPI, Config Service, Naming Service, and a Raft‑based consistency protocol for data synchronization.

Registration Mechanism

When a service starts, Spring Cloud’s AbstractAutoServiceRegistration listens for WebServerInitializedEvent . The concrete implementation NacosAutoServiceRegistration triggers super.register() , which ultimately calls NacosServiceRegistry.register() . This method delegates to the Nacos client SDK’s NamingService.registerInstance() to register the instance.

public interface ServiceRegistry
{
    void register(R registration);
    void deregister(R registration);
    void close();
    void setStatus(R registration, String status);
    <T> T getStatus(R registration);
}

The AutoServiceRegistrationAutoConfiguration class (declared in spring.factories ) auto‑configures the AutoServiceRegistration bean, which is implemented by NacosAutoServiceRegistration . This bean registers the service after the web server is initialized.

@Configuration(proxyBeanMethods = false)
@Import({AutoServiceRegistrationConfiguration.class})
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
public class AutoServiceRegistrationAutoConfiguration {
    @Autowired(required = false)
    private AutoServiceRegistration autoServiceRegistration;
    @Autowired
    private AutoServiceRegistrationProperties properties;
    @PostConstruct
    protected void init() {
        if (this.autoServiceRegistration == null && this.properties.isFailFast()) {
            throw new IllegalStateException("Auto Service Registration has been requested, but there is no AutoServiceRegistration bean");
        }
    }
}

During registration, Nacos performs a health‑check by creating a BeatInfo object and scheduling periodic heartbeats via beatReactor.addBeatInfo() . If the instance is healthy, serverProxy.registerService() sends an OpenAPI request with instance metadata.

public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
    LogUtils.NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
    String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
    BeatInfo existBeat = dom2Beat.remove(key);
    if (existBeat != null) {
        existBeat.setStopped(true);
    }
    dom2Beat.put(key, beatInfo);
    executorService.schedule(new BeatReactor.BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
    MetricsMonitor.getDom2BeatSizeMonitor().set((double) dom2Beat.size());
}

Discovery Mechanism

Service discovery is triggered when a consumer (e.g., a Feign client) invokes a remote interface. The NacosServerList.getServers() method calls NacosNamingService.selectInstances() to retrieve a list of healthy Instance objects.

public class NacosServerList extends AbstractServerList
{
    private List
getServers() {
        try {
            String group = discoveryProperties.getGroup();
            List
instances = discoveryProperties.namingServiceInstance()
                .selectInstances(serviceId, group, true);
            return instancesToServerList(instances);
        } catch (Exception e) {
            throw new IllegalStateException("Can not get service instances from nacos, serviceId=" + serviceId, e);
        }
    }
}

The NacosNamingService.selectInstances() method eventually delegates to HostReactor.getServiceInfo() , which maintains three concurrent maps: serviceInfoMap (cached service data), updatingMap (flags for ongoing updates), and futureMap (scheduled update tasks). If a service is not cached, updateServiceNow() fetches data from the server; otherwise, a periodic task created by scheduleUpdateIfAbsent() keeps the cache fresh.

public void scheduleUpdateIfAbsent(String serviceName, String clusters) {
    if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) == null) {
        synchronized (futureMap) {
            if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) == null) {
                ScheduledFuture
future = addTask(new HostReactor.UpdateTask(serviceName, clusters));
                futureMap.put(ServiceInfo.getKey(serviceName, clusters), future);
            }
        }
    }
}

Both registration and discovery rely heavily on the Raft consensus protocol for cluster consistency and on scheduled heartbeats for health monitoring. The article also provides practical debugging cases that illustrate the flow of registration and discovery, emphasizing the importance of having a web‑application context (i.e., spring-boot-starter-web ) for automatic registration.

Key Takeaways

Spring Cloud’s ServiceRegistry interface is the contract that Nacos implements via NacosServiceRegistry .

Automatic registration is driven by a web‑server event listener that invokes the Nacos client SDK.

Health checks are performed through periodic beat information; only healthy instances are registered.

Service discovery can use a subscription model (local cache) or direct server queries, both managed by HostReactor ’s map structures.

Raft ensures data consistency across Nacos server nodes.

javamicroservicesservice discoveryNacosSpring CloudService Registry
Code Ape Tech Column
Written by

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

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.