The foreword 0.
- Springboot version: 2.1.9.RELEASE
- Springcloud version: Greenwich.SR4
1. Process the client removal request
The cancelLease() method of the InstanceResource class handles client drop-off requests
// InstanceResource.class
public Response cancelLease(
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
// isReplication: indicates whether synchronous replication is performed between cluster nodes
try {
// 2 Handle client removal
boolean isSuccess = registry.cancel(app.getName(), id,
"true".equals(isReplication));
if (isSuccess) {
logger.debug("Found (Cancel): {} - {}", app.getName(), id);
// 200 is returned on success
return Response.ok().build();
} else {
logger.info("Not Found (Cancel): {} - {}", app.getName(), id);
// Processing failure returns 404
returnResponse.status(Status.NOT_FOUND).build(); }}catch (Throwable e) {
logger.error("Error (cancel): {} - {}", app.getName(), id, e);
// Handle an exception and return 500
returnResponse.serverError().build(); }}Copy the code
2. registry.cancel()
// PeerAwareInstanceRegistryImpl.class
public boolean cancel(final String appName, final String id,
final boolean isReplication) {
// 3 Call the parent class to handle the drop-off method
if (super.cancel(appName, id, isReplication)) {
// 2.1 Synchronizing replication to cluster Nodes
replicateToPeers(Action.Cancel, appName, id, null.null, isReplication);
synchronized (lock) {
if (this.expectedNumberOfClientsSendingRenews > 0) {
// Since the client wants to cancel it, reduce the number of clients to send renews
// After the processing is successful, the expected number of heartbeat renew instances received is -1
this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews - 1;
// 2.2 Updated the expected number of heartbeat renewal requests received per minuteupdateRenewsPerMinThreshold(); }}return true;
}
return false;
}
Copy the code
2.1 replicateToPeers ()
This is explained in EurekaServer- Synchronization Registry Mechanism
2.2 updateRenewsPerMinThreshold ()
This is explained in EurekaServer- Synchronization Registry Mechanism
3. super.cancel()
// AbstractInstanceRegistry.class
public boolean cancel(String appName, String id, boolean isReplication) {
return internalCancel(appName, id, isReplication);
}
protected boolean internalCancel(String appName, String id, boolean isReplication) {
try {
// Enable read lock
read.lock();
CANCEL.increment(isReplication);
// Get service lease information
Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
Lease<InstanceInfo> leaseToCancel = null;
if(gMap ! =null) {
If the service lease information exists, delete the instance lease information in it
leaseToCancel = gMap.remove(id);
}
synchronized (recentCanceledQueue) {
// Add the mapping between instance removal time and instance name to the latest removal queue
recentCanceledQueue.add(new Pair<Long, String>(System.currentTimeMillis(), appName + "(" + id + ")"));
}
/ / to get cover state, and deleted from the overriddenInstanceStatusMap
InstanceStatus instanceStatus = overriddenInstanceStatusMap.remove(id);
if(instanceStatus ! =null) {
logger.debug("Removed instance id {} from the overridden map which has value {}", id, instanceStatus.name());
}
if (leaseToCancel == null) {
CANCEL_NOT_FOUND.increment(isReplication);
logger.warn("DS: Registry: cancel failed because Lease is not registered for: {}/{}", appName, id);
// If the instance lease information is not available, return false
return false;
} else {
// In the instance lease information, set the time when the server is removed from the server
leaseToCancel.cancel();
InstanceInfo instanceInfo = leaseToCancel.getHolder();
String vip = null;
String svip = null;
if(instanceInfo ! =null) {
// Set the behavior type to delete
instanceInfo.setActionType(ActionType.DELETED);
// The instance change information is put into the latest change queue
recentlyChangedQueue.add(new RecentlyChangedItem(leaseToCancel));
// Set the latest modified timestamp for local instance information (non-dirty timestamp)
instanceInfo.setLastUpdatedTimestamp();
// Gets the virtual Internet protocol address of the instance. If not specified, the default is the host name
vip = instanceInfo.getVIPAddress();
// Gets the secure virtual Internet protocol address of the instance. If not specified, the default is the host name
svip = instanceInfo.getSecureVipAddress();
}
// invalidate the corresponding cache
invalidateCache(appName, vip, svip);
logger.info("Cancelled instance {}/{} (replication={})", appName, id, isReplication);
return true; }}finally {
// Close the read lockread.unlock(); }}Copy the code
4. To summarize
- When the server receives the client’s removal request, it obtains and deletes the lease information of the corresponding service instance from the local server
- Then the instances from the shelves of time and the service instance name mapping information added to the shelves recently queue, delete overriddenInstanceStatusMap covered the corresponding state
- Then record the takedown time in the instance lease information, convert it into the instance change information and add it to the latest change queue, and set the latest modified timestamp (non-dirty timestamp) of the corresponding instance information.
- Finally, the cache is invalidated and synchronized to the cluster node. The number of locally expected received heartbeat renewal instances is -1. The number of expected received heartbeat renewal requests per minute is updated