Make writing a habit together! This is the 8th day of my participation in the “Gold Digging Day New Plan · April More Text Challenge”. Click here for more details
Eureka Server service rejection logic
Have achieved unremittingly, indomitable than when subjected to failure is more important. — Larochivu
Eureka Server startup process analysis diagram + source code explain Eureka Client startup process analysis diagram + source code explain Eureka Server registry cache logic diagram + source code explain Eureka Client Eureka Client service registration process diagram + source code explain Eureka Client heartbeat mechanism process diagram + source code explain Eureka Client offline process analysis
Core flow chart
Where to start
In this method, the specific method implementation is carried out. In fact, if you think about it carefully, you know that the server side elimination logic is defined at the time of the server initialization
registry.openForTraffic(applicationInfoManager, registryCount);
Copy the code
Eliminate core ideas
Think carefully about how to eliminate, the client when initializing must be registered to the server, and regularly sends a heartbeat to the server after the service side of the heart, if not send a heartbeat instance there are placed into the queue, is placed into the did not send the heart of the queue, randomized instances, But if there are a lot of instances that are out of date then the data is compared, the expected number of heartbeats versus the actual number of heartbeats that were sent,
Elimination of core processes
Calculate the expected heartbeat count
The number of heartbeats is calculated based on the number of incoming instances, which is locally registered by the server after pulling values from other service nodes through the registry. SyncUp () method
public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
// Renewals happen every 30 seconds and for a minute it should be a factor of 2.
// Number of clients expected to send heartbeat
this.expectedNumberOfClientsSendingRenews = count;
// Expect the number of instances *2*0.85 heartbeats per minute
updateRenewsPerMinThreshold();
/** * Every 60 seconds, a scheduled background thread task, EvictionTask, fault instance removal task will be run */
super.postInit();
}
Copy the code
Update computation heartbeat logic updateRenewsPerMinThreshold (); Formula = Number of instances *(60s/30s)*0.85
protected void updateRenewsPerMinThreshold(a) {
/ / serverConfig. GetExpectedClientRenewalIntervalSeconds () the default 30 s
/ / 60.0 / serverConfig. GetExpectedClientRenewalIntervalSeconds () = = 2,
// serverConfig.getRenewalPercentThreshold())
// 2*0.85 is the expected number of instances *2*0.85 heartbeats per minute
this.numberOfRenewsPerMinThreshold = (int)
(this.expectedNumberOfClientsSendingRenews *
(60.0 / serverConfig.getExpectedClientRenewalIntervalSeconds()) *
serverConfig.getRenewalPercentThreshold());
}
Copy the code
Create a driver task to calculate the heartbeat value
Create a driver task and schedule it every 60 seconds
protected void postInit(a) {
renewsLastMin.start();
if(evictionTaskRef.get() ! =null) {
evictionTaskRef.get().cancel();
}
evictionTaskRef.set(new EvictionTask());
/** * The default is 60 seconds */
evictionTimer.schedule(evictionTaskRef.get(),
serverConfig.getEvictionIntervalTimerInMs(),
serverConfig.getEvictionIntervalTimerInMs());
}
Copy the code
Real elimination logic
Whether to enable the self-protection mechanism
IsSelfPreservationModeEnabled () default is open self protection mechanisms, so to calculate the last minutes of the heartbeat, and every minute of the heartbeat, and if one minute on the heartbeat than you expect would not protect itself mechanism move down below
if(! isLeaseExpirationEnabled()) {return;
}
public boolean isLeaseExpirationEnabled(a) {
if(! isSelfPreservationModeEnabled()) {// The self preservation mode is disabled, hence allowing the instances to expire.
return true;
}
return numberOfRenewsPerMinThreshold > 0 &&
getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
}
Copy the code
Filter out expired instances
Create a list of expired instances and run the lease. IsExpired () method through the registry to determine whether the current instance isExpired. If it is, add it to the expired list for subsequent operations
// Create a list of expired instances
List<Lease<InstanceInfo>> expiredLeases = new ArrayList<>();
/** * Pass through all the service instances in the registry and call Lease's isExpired() method * to determine if the Lease has expired or if the service instance is faulty. If it is, add it to a list */
for (Entry<String, Map<String, Lease<InstanceInfo>>> groupEntry : registry.entrySet()) {
Map<String, Lease<InstanceInfo>> leaseMap = groupEntry.getValue();
if(leaseMap ! =null) {
for (Entry<String, Lease<InstanceInfo>> leaseEntry : leaseMap.entrySet()) {
Lease<InstanceInfo> lease = leaseEntry.getValue();
if(lease.isExpired(additionalLeaseMs) && lease.getHolder() ! =null) {
// Put it in the expired list if it expiresexpiredLeases.add(lease); }}}}Copy the code
Calculate the limit on the number of expired instances
The default number of instances is 0.85, so if there are 40 instances, then it is 40 * 0.85 = 34 heartbeats, then the expired number limit is 40-34 = 6
// Get the number of instances in the local registry
int registrySize = (int) getLocalRegistrySize();// Suppose there are only 40 instances
/ * * * serverConfig. GetRenewalPercentThreshold () the default is 0.85 such as 40 examples it is * registrySizeThreshold = 0.85 * 40 = 34 the heartbeat * /
// Calculate the value of the least heartbeat sent
int registrySizeThreshold = (int) (registrySize *
serverConfig.getRenewalPercentThreshold());
// Calculate expired quantity limit using 40-34 = 6
int evictionLimit = registrySize - registrySizeThreshold;
Copy the code
Computing offline instances
Compare evictionLimit to the size of expired expiredLeases, fetch the minimum value, and then drop several random instances from the list of expired collections. Not all expired instances are removed. Only 15% of the instances in the registry are dropped at a time. The rest will be culled when the next task arrives
/** * Compare the size of evictionLimit to the expired expiredLeases and fetch the minimum */
int toEvict = Math.min(expiredLeases.size(), evictionLimit);
if (toEvict > 0) {
/** * The EvictionTask will be removed again the next time it is executed. The EvictionTask will be removed again the next time it executes. The batch removal mechanism * randomly selects the number of service instances that can be removed this time from the faulty instances to remove the service instances. The random removal mechanism * actually calls the offline method, internelCancel(), to remove the service instances. Registry, * recentChangeQueue, Invalidate cache */
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < toEvict; i++) {
int next = i + random.nextInt(expiredLeases.size() - i);
Collections.swap(expiredLeases, i, next);
Lease<InstanceInfo> lease = expiredLeases.get(i);
String appName = lease.getHolder().getAppName();
String id = lease.getHolder().getId();
EXPIRED.increment();
// take the instance offline
internalCancel(appName, id, false); }}Copy the code
Offline instance operation
InternalCancel offline instance operation is the shutdown operation of the client. Later, we will sort out the instance when it is offline, because this operation also involves the synchronization operation of the service cluster after it is offline, and an article will be presented to explain it later
summary
- Calculate the expected minimum number of beats per minute
- Check whether the self-protection mechanism is enabled by comparing the heartbeat rate in the last minute with the minimum expected heartbeat rate per minute
- If self-protection is not enabled then select (number of expired sets) and (registry minus expected minimum heartbeats per minute) to pick a minimum at random
- Take the filtered instance offline