Core Architecture Overview The self-preservation mechanism in Eureka Server is designed to handle network instability and prevent healthy services from being prematurely removed during communication failures.
Mechanism Behavior Eureka Server continuously monitors heartbeat success rates over 15-minute intervals. If the failure rate exceeds 15% (success rate drops below 85%), the server assumes network issues are affecting client communication. During this state:
Existing healthy instances are protected from expiration
New service registrations and queries are still accepted
Updates are not synchronized to other nodes to maintain local availability
Configuration Example
Demo configuration for sync failure scenarios
eureka.server.wait-time-in-ms-when-sync-empty=10000
Key Variables Two critical variables in AbstractInstanceRegistry: protected volatile int renewalThreshold; // Minimum expected renewals per minute protected volatile int expectedRenewalClients; // Expected number of clients sending renewals
Threshold Calculation
private void calculateRenewalThreshold() {
this.renewalThreshold = (int) (this.expectedRenewalClients
* (60.0 / serverConfig.getClientRenewalInterval())
* serverConfig.getRenewalPercentageThreshold());
}
Default client renewal interval: 30 seconds
Default threshold factor: 0.85 (85% minimum renewal requirement)
Variable Update Points
Server Initialization
protected void initializeServerContext() throws Exception {
EurekaServerConfig config = new DefaultEurekaServerConfig();
registry.activateTraffic(applicationManager, instanceCount);
}
Traffic Activation
public void activateTraffic(ApplicationManager manager, int count) {
this.expectedRenewalClients = count;
calculateRenewalThreshold();
// Additional initialization logic
}
Instance Removal
protected boolean removeInstance(String appName, String id, boolean replication) {
synchronized (lock) {
if (this.expectedRenewalClients > 0) {
this.expectedRenewalClients--;
calculateRenewalThreshold();
}
}
return true;
}
New Registration
public void register(InstanceInfo info, int leaseDuration, boolean replication) {
synchronized (lock) {
if (this.expectedRenewalClients > 0) {
this.expectedRenewalClients++;
calculateRenewalThreshold();
}
}
// Additional registration logic
}
Periodic Threshold Update
private void scheduleThresholdUpdate() {
timer.schedule(new TimerTask() {
@Override
public void run() {
refreshThreshold();
}
}, serverConfig.getThresholdUpdateInterval(),
serverConfig.getThresholdUpdateInterval());
}
Self-Preservation Task
protected void finalizeInitialization() {
renewalMonitor.start();
if (evictionTask.get() != null) {
evictionTask.get().cancel();
}
evictionTask.set(new CleanupTask());
evictionTimer.schedule(evictionTask.get(),
serverConfig.getCleanupInterval(),
serverConfig.getCleanupInterval());
}
Cleanup Logic
private final AtomicLong lastRunNanos = new AtomicLong(0l);
@Override
public void run() {
try {
long adjustmentTime = getAdjustmentTime();
performCleanup(adjustmentTime);
} catch (Throwable e) {
logger.error("Cleanup execution failed", e);
}
}
Expiration Control
public boolean isExpirationAllowed() {
if (!isProtectionActive()) {
return true;
}
return renewalThreshold > 0 && getCurrentRenewals() > renewalThreshold;
}