How Nacos Implements Health Checks and Heartbeats: A Deep Dive into Client and Server Mechanics
This article explains Nacos's health‑check and heartbeat mechanism in detail, covering the client‑side heartbeat scheduling, metadata configuration, server‑side beat reception, instance health evaluation, and the periodic health‑check tasks that mark or remove unhealthy instances.
Introduction
Nacos uses a heartbeat‑based health‑check for temporary (ephemeral) instances. The client sends a heartbeat every 5 seconds; if the server does not receive a beat within 15 seconds the instance is marked unhealthy, and after 30 seconds it is removed.
Client‑Side Heartbeat
Spring Cloud creates a NacosServiceRegistry and calls its register method during startup. The method builds a Instance from the registration metadata, which includes health‑check parameters such as heart-beat-interval, heart-beat-timeout and ip-delete-timeout:
spring:
application:
name: user-service-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
heart-beat-interval: 5000
heart-beat-timeout: 15000
ip-delete-timeout: 30000The registerInstance call adds the instance to BeatReactor if it is ephemeral, which creates a BeatInfo and schedules a BeatTask:
public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
dom2Beat.put(key, beatInfo);
executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
}The interval comes from Instance#getInstanceHeartBeatInterval(), which reads the metadata key preserved.heart.beat.interval (default 5 seconds).
public long getInstanceHeartBeatInterval() {
return this.getMetaDataByKeyWithDefault("preserved.heart.beat.interval", Constants.DEFAULT_HEART_BEAT_INTERVAL);
}The BeatTask sends the beat via NamingProxy#sendBeat and reschedules itself:
public void run() {
if (beatInfo.isStopped()) return;
JsonNode result = serverProxy.sendBeat(beatInfo, lightBeatEnabled);
long interval = result.get("clientBeatInterval").asLong();
if (interval > 0) nextTime = interval;
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
}The sendBeat method performs an HTTP PUT to /instance/beat on the Nacos server.
Server‑Side Beat Reception
The server endpoint /beat is implemented in InstanceController. It either registers a missing instance or forwards the beat to the service’s processClientBeat method:
public ObjectNode beat(HttpServletRequest request) throws Exception {
Instance instance = serviceManager.getInstance(...);
if (instance == null) {
instance = new Instance();
// set fields from clientBeat
serviceManager.registerInstance(namespaceId, serviceName, instance);
}
service.processClientBeat(clientBeat);
return result;
} processClientBeatcreates a ClientBeatProcessor task and schedules it for immediate execution:
public void processClientBeat(final RsInfo rsInfo) {
ClientBeatProcessor task = new ClientBeatProcessor();
task.setService(this);
task.setRsInfo(rsInfo);
HealthCheckReactor.scheduleNow(task);
}The processor updates the instance’s lastBeat timestamp and, if the instance was previously unhealthy, marks it healthy and publishes a ServiceChangeEvent.
Server‑Side Periodic Health Check
When a service is created, Service.init() schedules a recurring ClientBeatCheckTask via HealthCheckReactor.scheduleCheck (every 5 seconds):
public static void scheduleCheck(ClientBeatCheckTask task) {
GlobalExecutor.scheduleNamingHealth(task, 5000, 5000, TimeUnit.MILLISECONDS);
}The task iterates over all instances. If the current time minus lastBeat exceeds instanceHeartBeatTimeOut, the instance is marked unhealthy and a heartbeat‑timeout event is published. If the time exceeds ipDeleteTimeout and the instance is not marked, it is removed.
public void run() {
for (Instance instance : instances) {
if (System.currentTimeMillis() - instance.getLastBeat() > instance.getInstanceHeartBeatTimeOut()) {
if (instance.isHealthy()) {
instance.setHealthy(false);
getPushService().serviceChanged(service);
ApplicationUtils.publishEvent(new InstanceHeartbeatTimeoutEvent(this, instance));
}
}
}
if (!getGlobalConfig().isExpireInstance()) return;
for (Instance instance : instances) {
if (System.currentTimeMillis() - instance.getLastBeat() > instance.getIpDeleteTimeout()) {
deleteIp(instance);
}
}
}Conclusion
The source code shows the full lifecycle of Nacos health checks: client‑side heartbeat scheduling and metadata configuration, server‑side beat reception that updates instance state, and a periodic health‑check task that marks stale instances as unhealthy or removes them entirely. Understanding these mechanisms helps developers tune heartbeat intervals, timeouts, and apply similar patterns in custom service‑registry solutions.
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.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
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.
