Dubbo implementation principle and source code analysis — Fine collection Netty implementation principle and source code analysis — boutique collection
“Spring Implementation principles and source code analysis — Boutique Collection” MyBatis implementation principle and source code analysis — boutique collection
Spring MVC Implementation Principle and source code Analysis — A collection of fine works Database Entity Design Collection
Spring Boot Implementation principle and source code analysis — Boutique Collection Java Interview Questions + Java Learning Guide

Abstract: the original source www.iocoder.cn/Eureka/inst… “Taro source” welcome to reprint, keep the summary, thank you!

This article is mainly based on Eureka version 1.8.X

  • 1. An overview of the
  • 2. The application instance overrides the interface for status change
    • 2.1 Updating the coverage status of an application instance
  • 3. Delete the interface from the overwriting status of the application instance
    • 3.1 Deleting the Overwrite Status of an Application Instance
  • 4. The application instance overrides the status mapping
    • 4.1 Application Instance Status Overwriting Rules
    • 4.2 Registration Scenarios
    • 4.3 Lease Renewal Scenario
    • 4.4 Offline Scenario
    • 4.5 Expiration Scenario
  • 5. The client invokes the interface
  • 666. The eggs

🙂🙂🙂 follow wechat public number:

  1. RocketMQ/MyCAT/Sharding-JDBC all source code analysis article list
  2. RocketMQ/MyCAT/Sharding-JDBC 中文 解 决 source GitHub address
  3. Any questions you may have about the source code will be answered carefully. Even do not know how to read the source can also ask oh.
  4. New source code parsing articles are notified in real time. It’s updated about once a week.
  5. Serious source communication wechat group.

1. An overview of the

This article focuses on sharing coverage status attributes of application instances.

Note that this is not the status of the application instance, but the overridestatus. The code is as follows:

public class InstanceInfo { private volatile InstanceStatus overriddenstatus = InstanceStatus.UNKNOWN; / /... Omit properties and methods}Copy the code

Call eureka-Server HTTP Restful interface apps/${APP_NAME}/${INSTANCE_ID}/status to overwrite the status change of an application instance. In this way, the status of an application instance can be changed actively and forcibly. Note that you do not actually change the state of the Eureka-Client application instance, but the state of the application instance registered with eureka-Server.

In such a way, Eureka – the Client registered in access to information, and configuration. Eureka shouldFilterOnlyUpInstances = true, filters out the InstanceStatus. The application example of UP, to avoid the instance and To suspend the application instance (InstanceStatus.OUT_OF_SERVICE) without closing the application instance.

Therefore, in most cases, the purpose of calling this interface is to switch the application instance state between (InstanceStatus.UP) and (InstanceStatus.OUT_OF_SERVICE). The comments on the official code quote are as follows:

Abstractinstanceregistrystatusupdate abstractInstanceregistrystatusUpdate abstractUpdates the status of an instance. Normally happens to put an instance between {@link InstanceStatus#OUT_OF_SERVICE} and {@link InstanceStatus#UP} to put the instance in and out of traffic.


Recommended Spring Cloud books:

  • Please support the legal version. Download piracy, is equal to the initiative to write low-level bugs.
  • DD — Spring Cloud Micro Services
  • Zhou Li — “Spring Cloud and Docker Micro-service Architecture Combat”
  • Buy two books together, jingdong free delivery.

Interface apps/${APP_NAME}/${INSTANCE_ID}/status

  • PUT apps/${APP_NAME}/${INSTANCE_ID}/status
  • DELETE apps/${APP_NAME}/${INSTANCE_ID}/status

Below, we share the code implementation of both interfaces section by section.

2. The application instance overrides the interface for status change

The InstanceResource#statusUpdate() method is mapped as follows:

@PUT @Path("status") public Response statusUpdate( @QueryParam("value") String newStatus, @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication, @queryParam ("lastDirtyTimestamp") String lastDirtyTimestamp) {try {// The application instance does not exist if (registry.getInstanceByAppAndId(app.getName(), id) == null) { logger.warn("Instance not found: {}/{}", app.getName(), id); return Response.status(Status.NOT_FOUND).build(); } Boolean isSuccess = registry. StatusUpdate (app.getName(), id, InstanceStatus. ValueOf (newStatus), lastDirtyTimestamp, "true".equals(isReplication)); If (isSuccess) {logger.info("Status updated: "+ app.getName() +" - "+ ID +" - "+ newStatus); return Response.ok().build(); } else { logger.warn("Unable to update status: " + app.getName() + " - " + id + " - " + newStatus); return Response.serverError().build(); } } catch (Throwable e) { logger.error("Error updating instance {} for status {}", id, newStatus); return Response.serverError().build(); }}Copy the code
  • Call PeerAwareInstanceRegistryImpl# statusUpdate (…). Method to update the application instance coverage status. The implementation code is as follows:

    @Override public boolean statusUpdate(final String appName, final String id, final InstanceStatus newStatus, String lastDirtyTimestamp, final boolean isReplication) { if (super.statusUpdate(appName, id, newStatus, // Eureka-Server replicateToPeers(action.statusUpdate, appName, ID, null, newStatus, isReplication); return true; } return false; }Copy the code
    • Call the parent classAbstractInstanceRegistry#statusUpdate(...)Method to update the application instance coverage status.

2.1 Updating the coverage status of an application instance

Call AbstractInstanceRegistry# statusUpdate (…). Method, update the application instance coverage status, the implementation code is as follows:

1: @Override 2: public boolean statusUpdate(String appName, String id, 3: InstanceStatus newStatus, String lastDirtyTimestamp, 4: Boolean isReplication) {5: try {6: // Obtain a read lock 7: read.lock(); 8: // Add the number of overwrite status changes to monitor 9: status_update.increment (isReplication); 11: Map<String, Lease<InstanceInfo>> gMap = registry. Get (appName); 12: Lease<InstanceInfo> lease = null; 13: if (gMap ! = null) { 14: lease = gMap.get(id); 17: if (lease == null) {18: return false; 19:} else {20: // set lease. Renew () 21: lease. 22:23: // Application instance information does not exist (defensive programming) 24: InstanceInfo info = lease. GetHolder (); 25: // Lease is always created with its instance info object. 26: // This log statement is provided as a safeguard, in case this invariant is violated. 27: if (info == null) { 28: logger.error("Found Lease without a holder for instance id {}", id); 29: } 30: // 31: if ((info ! = null) && ! (info.getStatus().equals(newStatus))) {32: // Mark service as UP if needed 34: if (InstanceStatus.UP.equals(newStatus)) { 35: lease.serviceUp(); 36:37} : / / added to the application instance to cover state map 38: / / This is NAC overridden status: 39 overriddenInstanceStatusMap. Put (id, newStatus); 42: // Set it for transfer of overridden status to replica on 42: // Replica start up 43: info.setOverriddenStatus(newStatus); 45: Long replicaDirtyTimestamp = 0; 45: Long replicaDirtyTimestamp = 0; 47:46: / / set application instance state info. SetStatusWithoutDirty (newStatus); 48: if (lastDirtyTimestamp ! = null) { 49: replicaDirtyTimestamp = Long.valueOf(lastDirtyTimestamp); 50: } 51: // If the replication's dirty timestamp is more than the existing one, just update 52: // it to the replica's. 53: if (replicaDirtyTimestamp > info.getLastDirtyTimestamp()) { 54: info.setLastDirtyTimestamp(replicaDirtyTimestamp); } 56: // Add to the latest lease change queue 57: info.setActionType(actiontype.modified); 58: recentlyChangedQueue.add(new RecentlyChangedItem(lease)); 59: / / set The last update time: 60 info. SetLastUpdatedTimestamp (); 62: invalidateCache(appName, info.getVipAddress (), info.getSecureVipAddress())); 63: } 64: return true; 65:} 66:} finally {67: // unlock 68: read-.unlock (); 69:} 70:}Copy the code
  • Lines 6-7: Get the read lock. In “Eureka source code analysis – application instance registration discovery (nine) years is the MOE read and write lock” detailed analysis.
  • Line 8 through 9: Add the number of override state changes to the monitor. Cooperate with Netflix Servo to realize monitoring information collection.
  • Lines 10 to 15: Obtain a lease.
  • Lines 16 to 18: Lease does not exist, return update failed.
  • Lines 20 to 21: Set the last renewal date of the lease (renewal).
  • Lines 23 to 29: There are no lease application instances, and in theory there will be no defensive programming.
  • Line 31: Update the override state only if the current state of the application instance is inconsistent with the override state.
  • Lines 32 to 36: when the overwrite state isInstanceStatus.UP, sets the time stamp of the lease’s start service (valid only for the first time).
  • Line 37 to 39: cover mapping (overriddenInstanceStatusMap) added to the application examples. “NAC” may stand for “Network Access Control”. If you are interested, check out “Network Access Control”. OverriddenInstanceStatusMap attribute code is as follows:

    /** * Application instance overwrite status mapping * key: Application instance id */ protected Final ConcurrentMap<String, InstanceStatus> overriddenInstanceStatusMap = CacheBuilder .newBuilder().initialCapacity(500) .expireAfterAccess(1, TimeUnit.HOURS) .<String, InstanceStatus>build().asMap();Copy the code
    • Valid for 1 hour. The expiration date is refreshed after each visit, which you will see later.
  • Lines 40 through 43: Set the overlay state of the application instance. It is used for eureka-Server cluster synchronization.

  • Lines 46 through 47: Set the application instance state. After the configuration, Eureka-client pulls the registration information, and the application instance whose status is overwritten by the update is the configured status.
  • Lines 48 through 55: Set the data inconsistency time for the application instance. It is used for eureka-Server cluster synchronization.
  • Lines 56 through 58: Add the application instance to the latest Lease Change record queue.
  • Line 59 to 60: Set the last update time of the application instance (lastUpdatedTimestamp).lastUpdatedTimestampIt is used to record the last update time and has no actual service purpose.
  • Line 61 through 62: Set the response cache to expire.
  • Line 64: Returns update success.
  • Line 68: Release the read lock.

3. Delete the interface from the overwriting status of the application instance

When we do not need the overwrite state of the application instance, the scheduling interface interface is deleted. Issue# 89: Provide an API to remove all overridden status.

The InstanceResource#deleteStatusUpdate() method is mapped as follows:

@DELETE @Path("status") public Response deleteStatusUpdate( @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication, @QueryParam("value") String newStatusValue, @queryParam ("lastDirtyTimestamp") String lastDirtyTimestamp) {try {// The application instance does not exist if (registry.getInstanceByAppAndId(app.getName(), id) == null) { logger.warn("Instance not found: {}/{}", app.getName(), id); return Response.status(Status.NOT_FOUND).build(); } InstanceStatus newStatus = newStatusValue == null? InstanceStatus.UNKNOWN : InstanceStatus.valueOf(newStatusValue); boolean isSuccess = registry.deleteStatusOverride(app.getName(), id, newStatus, lastDirtyTimestamp, "true".equals(isReplication)); If (isSuccess) {logger.info("Status Override removed: "+ app.getName() +" - "+ id); return Response.ok().build(); } else { logger.warn("Unable to remove status override: " + app.getName() + " - " + id); return Response.serverError().build(); } } catch (Throwable e) { logger.error("Error removing instance's {} status override", id); return Response.serverError().build(); }}Copy the code
  • Request parametersnewStatusValueTo set the status of the application instance. For the most part,newStatusValueThe value must be consistent with the actual status of the application instance, because the Eureka-client of the application instance does not pull the application state from the Eureka-servernewStatusValue. The other way, without passing this argument, is equivalent toUNKNOWNIn this case, eureka-client initiates registration with Eureka-server again. For details, see 4.3 Lease Renewal Scenario.
  • Call AbstractInstanceRegistry#deleteStatusOverride(…) Method to delete the application instance overwrite status. The implementation code is as follows:

    @Override public boolean deleteStatusOverride(String appName, String id, InstanceStatus newStatus, String lastDirtyTimestamp, boolean isReplication) { if (super.deleteStatusOverride(appName, id, newStatus, LastDirtyTimestamp isReplication)) {/ / Eureka - Server cluster synchronization replicateToPeers (Action. DeleteStatusOverride, appName, id, null, null, isReplication); return true; } return false; }Copy the code
    • Call the parent classAbstractInstanceRegistry#deleteStatusOverride(...)Method to delete the application instance overwrite status.

3.1 Deleting the Overwrite Status of an Application Instance

Call AbstractInstanceRegistry#deleteStatusOverride(…) Method to delete the application instance overwrite status. The implementation code is as follows:

1: @Override 2: public boolean deleteStatusOverride(String appName, String id, 3: InstanceStatus newStatus, 4: String lastDirtyTimestamp, 5: Boolean isReplication) {6: try {7: // obtain read lock 8: read.lock(); 10: status_override_delete. increment(isReplication); 12: Map<String, Lease<InstanceInfo>> gMap = registry. Get (appName); 13: Lease<InstanceInfo> lease = null; 14: if (gMap ! = null) { 15: lease = gMap.get(id); If (lease == null) {19: return false; } else {21: // set lease. Renew () 22: lease. 23:24: // Application instance information does not exist (defensive programming) 25: InstanceInfo info = lease. GetHolder (); 26: // Lease is always created with its instance info object. 27: // This log statement is provided as a safeguard, in case this invariant is violated. 28: if (info == null) { 29: logger.error("Found Lease without a holder for instance id {}", id); 30:31} : 32: / / remove applications cover 33: InstanceStatus currentOverride = overriddenInstanceStatusMap. Remove (id); 34: if (currentOverride ! = null && info ! = null) {35: // Set the application instance override status 36: info.setoverriddenStatus (InstanceStatus.UNKNOWN); 37: / / set application instance state 38: info. SetStatusWithoutDirty (newStatus); 40: long replicaDirtyTimestamp = 0; 40: Long replicaDirtyTimestamp = 0; 41: if (lastDirtyTimestamp ! = null) { 42: replicaDirtyTimestamp = Long.valueOf(lastDirtyTimestamp); 43: } 44: // If the replication's dirty timestamp is more than the existing one, just update 45: // it to the replica's. 46: if (replicaDirtyTimestamp > info.getLastDirtyTimestamp()) { 47: info.setLastDirtyTimestamp(replicaDirtyTimestamp); 49:} 49: // Add to the latest lease change queue 50: info.setActionType(actiontype.modified); 51: recentlyChangedQueue.add(new RecentlyChangedItem(lease)); 52: / / set Last update time 53: info. SetLastUpdatedTimestamp (); 55: invalidateCache(appName, info.getVipAddress (), info.getSecureVipAddress())); 56: } 57: return true; 58:} 59:} finally {60: // unlock 61: read-.unlock (); 62:} 63:}Copy the code
  • Lines 7 through 8: Get the read lock. In “Eureka source code analysis – application instance registration discovery (nine) years is the MOE read and write lock” detailed analysis.
  • Line 9 through 10: Add the number of overwrite state deletions to monitor. Cooperate with Netflix Servo to realize monitoring information collection.
  • Lines 11 to 16: Obtain a lease.
  • Lines 17 to 19: Lease does not exist, return update failed.
  • Lines 21 to 22: Set the last renewal date of the lease (renewal).
  • Lines 24 to 30: There is no instance of an application holding a lease, and in theory there is no such thing as defensive programming.
  • Line 32 to 33: Remove the application instance override state map (overriddenInstanceStatusMap).
  • Line 34: Set the state only when the overwrite state of the application instance exists.
  • Line 35 through 36: Set the override status of the application instance to InstanceStatus.UNKNOWN. It is used for eureka-Server cluster synchronization.
  • Lines 37 through 38: Set the state of the application instance tonewStatus. After the configuration, Eureka-client pulls the registration information, and the application instance whose status is overwritten by the update is the configured status.
  • Lines 39 through 48: Set the data inconsistency time for the application instance. It is used for eureka-Server cluster synchronization.
  • Lines 49 through 51: Add the application instance to the recent Lease Change record queue.
  • Line 52 to 53: Set the last update time of the application instance (lastUpdatedTimestamp).lastUpdatedTimestampIt is used to record the last update time and has no actual service purpose.
  • Line 54 through 55: Set the response cache to expire.
  • Line 57: Returns update success.
  • Line 61: Release the read lock.

4. The application instance overrides the status mapping

Although we in the above code, the use of cover (overridestatus) set to an instance application state (status), actual call AbstractInstanceRegistry# getOverriddenInstanceStatus (…). Method, according to the rules of application instance state coverage (InstanceStatusOverrideRule) to calculate the final application instance. The implementation code is as follows:

// AbstractInstanceRegistry.java
protected InstanceInfo.InstanceStatus getOverriddenInstanceStatus(InstanceInfo r,
                                                               Lease<InstanceInfo> existingLease,
                                                               boolean isReplication) {
   InstanceStatusOverrideRule rule = getInstanceInfoOverrideRule();
   logger.debug("Processing override status using rule: {}", rule);
   return rule.apply(r, existingLease, isReplication).status();
}

protected abstract InstanceStatusOverrideRule getInstanceInfoOverrideRule();
Copy the code
  • Call # getInstanceInfoOverrideRule () method, to obtain application instance state rules (InstanceStatusOverrideRule). The method in PeerAwareInstanceRegistryImpl implementation code is as follows:

    private final InstanceStatusOverrideRule instanceStatusOverrideRule; public PeerAwareInstanceRegistryImpl( EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, ServerCodecs serverCodecs, EurekaClient eurekaClient ) { // ... Omit this. Other method instanceStatusOverrideRule = new FirstMatchWinsCompositeRule (new DownOrStartingRule (), new OverrideExistsRule(overriddenInstanceStatusMap), new LeaseExistsRule()); } @Override protected InstanceStatusOverrideRule getInstanceInfoOverrideRule() { return this.instanceStatusOverrideRule;  }Copy the code

4.1 Application Instance Status Overwriting Rules

Com.net flix. Eureka. Registry. Rule. InstanceStatusOverrideRule, application instance state rules cover interface. The interface code is as follows:

// InstanceStatusOverrideRule.java public interface InstanceStatusOverrideRule { /** * Match this rule. * * @param instanceInfo The instance info whose status we care about. * @param existingLease Does the instance have an existing lease already? Now let's consider that. * @param isReplication When overriding consider If we are under a replication mode from other servers. @return A result with whether we matched and what we choose the status to be overriden to. */  StatusOverrideResult apply(final InstanceInfo instanceInfo, final Lease<InstanceInfo> existingLease, boolean isReplication); } // StatusOverrideResult.java public class StatusOverrideResult { public static StatusOverrideResult NO_MATCH = new StatusOverrideResult(false, null); public static StatusOverrideResult matchingStatus(InstanceInfo.InstanceStatus status) { return new StatusOverrideResult(true, status); } // Does the rule match? private final boolean matches; // The status computed by the rule. private final InstanceInfo.InstanceStatus status; private StatusOverrideResult(boolean matches, InstanceInfo.InstanceStatus status) { this.matches = matches; this.status = status; } public boolean matches() { return matches; } public InstanceInfo.InstanceStatus status() { return status; }}Copy the code

The implementation class relationship is as follows:

  • AsgEnabledRule, amazon AWS exclusive, skip.

4.1.1 FirstMatchWinsCompositeRule

Com.net flix. Eureka. Registry. Rule. FirstMatchWinsCompositeRule, compound rules, will be subject to the first matching success. The implementation code is as follows:

Public class FirstMatchWinsCompositeRule implements InstanceStatusOverrideRule {/ composite rules set * * * * / private final InstanceStatusOverrideRule[] rules; / * * * the default rules * / private final InstanceStatusOverrideRule defaultRule; private final String compositeRuleName; public FirstMatchWinsCompositeRule(InstanceStatusOverrideRule... rules) { this.rules = rules; this.defaultRule = new AlwaysMatchInstanceStatusRule(); // Let's build up and "cache" the rule name to be used by toString(); List<String> ruleNames = new ArrayList<>(rules.length+1); for (int i = 0; i < rules.length; ++i) { ruleNames.add(rules[i].toString()); } ruleNames.add(defaultRule.toString()); compositeRuleName = ruleNames.toString(); } @Override public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, For (int I = 0; int I = 0; i < this.rules.length; ++i) { StatusOverrideResult result = this.rules[i].apply(instanceInfo, existingLease, isReplication); if (result.matches()) { return result; }} // return defaultrule. apply(instanceInfo, existingLease, isReplication) using the defaultRule; } @Override public String toString() { return this.compositeRuleName; }}Copy the code
  • rulesProperties,compositeSet of rules. In PeerAwareInstanceRegistryImpl, we can see the properties for [DownOrStartingRule OverrideExistsRule, LeaseExistsRule].
  • defaultRuleAttribute, a default rules, the value of AlwaysMatchInstanceStatusRule.
  • #apply()Method, preferentially usedcompositeRules (rules) in order until the match succeeds. If the match is not successful, use the default rule (defaultRule).

4.1.2 DownOrStartingRule

Com.net flix. Eureka. Registry. Rule. DownOrStartingRule, Match the InstanceInfo. InstanceStatus. DOWN or InstanceInfo. InstanceStatus. STARTING state. # the apply (…). The code is as follows:

@Override public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, boolean isReplication) { // ReplicationInstance is DOWN or STARTING - believe that, but when the instance says UP, question that // The client instance sends STARTING or DOWN (because of heartbeat failures), then we accept what // the client says. The same is the case with replica as well. // The OUT_OF_SERVICE from the client  or replica needs to be confirmed as well since the service may be // currently in SERVICE if ((! InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())) && (! InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(instanceInfo.getStatus()))) { logger.debug("Trusting the instance status {} from replica or instance for instance {}", instanceInfo.getStatus(), instanceInfo.getId()); return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); } return StatusOverrideResult.NO_MATCH; }Copy the code
  • Pay attention to, usinginstanceInfo

4.1.3 OverrideExistsRule

Com.net flix. Eureka. Registry. Rule. OverrideExistsRule, matching applications cover mapping (statusOverrides). # the apply (…). The code is as follows:

public class OverrideExistsRule implements InstanceStatusOverrideRule {

   private Map<String, InstanceInfo.InstanceStatus> statusOverrides;

    @Override
    public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, boolean isReplication) {
        InstanceInfo.InstanceStatus overridden = statusOverrides.get(instanceInfo.getId());
        // If there are instance specific overrides, then they win - otherwise the ASG status
        if (overridden != null) {
            logger.debug("The instance specific override for instance {} and the value is {}",
                    instanceInfo.getId(), overridden.name());
            return StatusOverrideResult.matchingStatus(overridden);
        }
        return StatusOverrideResult.NO_MATCH;
    }

}
Copy the code
  • statusOverridesProperty, the application instance overrides the state map. In PeerAwareInstanceRegistryImpl, useAbstractInstanceRegistry.overriddenInstanceStatusMapAttribute assignment.
  • As mentioned aboveAbstractInstanceRegistry.overriddenInstanceStatusMapThe validity period is refreshed with each access, and continuously refreshed if OverrideExistsRule is called. As you can see from downorstar Rule,instanceInfoIn aInstanceInfo.InstanceStatus.DOWNorInstanceInfo.InstanceStatus.STARTINGSo you don’t call the OverrideExistsRule match,AbstractInstanceRegistry.overriddenInstanceStatusMapIt is possible to expire.

4.1.4 LeaseExistsRule

Com.net flix. Eureka. Registry. Rule. LeaseExistsRule, Match existing lease application example nstanceStatus. OUT_OF_SERVICE or InstanceInfo. InstanceStatus. The UP state. # the apply (…). The code is as follows:

public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease<InstanceInfo> existingLease, boolean isReplication) { // This is for backward compatibility until all applications have ASG // names, otherwise while starting up // the client status may override status replicated from other servers if (! IsReplication) {/ / the Eureka - Server request InstanceInfo. InstanceStatus existingStatus = null; if (existingLease ! = null) { existingStatus = existingLease.getHolder().getStatus(); } // Allow server to have its way when the status is UP or OUT_OF_SERVICE if ((existingStatus ! = null) && (InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(existingStatus) || InstanceInfo.InstanceStatus.UP.equals(existingStatus))) { logger.debug("There is already an existing lease with status {} for instance {}", existingLease.getHolder().getStatus().name(), existingLease.getHolder().getId()); return StatusOverrideResult.matchingStatus(existingLease.getHolder().getStatus()); } } return StatusOverrideResult.NO_MATCH; }Copy the code
  • Pay attention to, usingexistingLease, and non-Eureka-server requests.

4.1.5 AlwaysMatchInstanceStatusRule

Com.net flix. Eureka. Registry. Rule. AlwaysMatchInstanceStatusRule, always match pay attention to the object instance (instanceInfo) state of the state. # the apply (…). The code is as follows:

@Override
public StatusOverrideResult apply(InstanceInfo instanceInfo,
                                 Lease<InstanceInfo> existingLease,
                                 boolean isReplication) {
   logger.debug("Returning the default instance status {} for instance {}", instanceInfo.getStatus(),
           instanceInfo.getId());
   return StatusOverrideResult.matchingStatus(instanceInfo.getStatus());
}
Copy the code
  • Pay attention to, usinginstanceInfo

4.1.6 summary

We will comb PeerAwareInstanceRegistryImpl applications cover state rules are as follows:

  • Application instance state is one of the most important attributes, so in the final instance state calculation, reliability is the main.
  • DownOrStartingRule,instanceInfoIn aSTARTINGorDOWNStatus, the application instance may not be suitable to provide the service (being requested), considerA reliableTo return toinstanceInfoIn the state.
  • OverrideExistsRule, when there is an overwrite state (statusoverrides), using this state, it is easier to understand.
  • LeaseExistsRule, request from Eureka-client (non-Eureka-server cluster request) when the instance of Eureka-Server is in stateThere areAnd in theUPorOUT_OF_SERVICETo retain the current state. The reason,It is forbidden for Eureka-client to actively switch between the two states. If switching is required, override the state change and delete interface with the application instance.
  • AlwaysMatchInstanceStatusRule, useinstanceInfoTo ensure that the state is matched.
  • As you will see below,#getOverriddenInstanceStatus()Methods inregisteredandFor renewalTo use. Combined with the figure above, we are at4.2 Registration Scenario 和 4.3 Lease Renewal ScenarioIt will also be dissected in detail.
  • As you will see below,#getOverriddenInstanceStatus()Methods inregisteredandFor renewalUsing the method parametersinstanceInfoThe situation is as follows:
    • The time of registration: Request parametersinstanceInfo, andexistingLeaseThe application instance attributes of eureka-server are not equal (if you consider eureka-server’sLastDirtyTimestampLarger cases are similarThe situation at the time of renewal).
    • When the lease: Using eureka-serverexistingLeaseThe two are equivalent.
    • In general, can beinstanceInfoUnderstood as the state of the requester.
  • DownOrStartingRule,

4.2 Registration Scenarios

// AbstractInstanceRegistry.java 1: public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) { 2: try { 3: Map<String, Lease<InstanceInfo>> gMap = registry. Get (registrant.getAppName()); 5: // (omit code) increase the number of registrations to monitor 6: // (omit code) get the application instance information corresponding to the lease 7: Lease<InstanceInfo> existingLease = gMap.get(registrant.getId()); 8: // Retain the last dirty timestamp without overwriting it, if there is already a lease 9: if (existingLease ! = null && (existingLease.getHolder() ! = null)) {// (omit code) already exists, use data inconsistent time large application registration information is valid 10:} else {11: // The lease does not exist and hence it is a new registration 12: / / code (omitted) increase self-protection mechanism 】 【 ` numberOfRenewsPerMinThreshold `, ` expectedNumberOfRenewsPerMin ` 13:} 14: / / create the lease 15: Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration); 16: if (existingLease ! = null) {/ / if the lease has been in existence, the timestamp of 17 to set the start of the lease service: lease. SetServiceUpTimestamp (existingLease. GetServiceUpTimestamp ()); 20: gmap.put (registrant.getid (), lease); 21: // (omit code) add to the recently registered debug queue 22: // (omit code) add to the application instance override state map (used for eureka-server initialization) 23: // Set the application instance override state 24: InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId()); 25: if (overriddenStatusFromMap ! = null) { 26: logger.info("Storing overridden status {} from map", overriddenStatusFromMap); 27: registrant.setOverriddenStatus(overriddenStatusFromMap); 31: // Set the status based on the overridden status rules 32: InstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease, isReplication); 33: / / set application instance state 34: registrant. SetStatusWithoutDirty (overriddenInstanceStatus); 35: 36: // (omitted code) Set the time stamp of the lease start service (valid only for the first time) 37: // (omitted code) set the operation type of the application instance information to Add 38: // (omitted code) Add to the latest lease change queue 39: // Finally {42: // finally {42: // (omitted code) release lock 43:} 44:}Copy the code
  • Line 7: GetexistingLease (existingLease).
  • Line 15: CreateThe newThe lease,lease).
  • Line 24 to 28: Set the overlay state of the application instance (overridestatus) to avoid the loss of coverage status after application instances are registered.
  • Lines 30 to 32:Obtain the final status of the application instance. Notice that, regardless of line 9,registrantexistingLeaseApplication instances are not the same object.
  • Line 33, line 34: Sets the state of the application instance.

4.3 Lease Renewal Scenario

// AbstractInstanceRegistry.java 1: public boolean renew(String appName, String id, boolean isReplication) { 2: 4: Map<String, Lease<InstanceInfo>> gMap = registry. Get (appName); 5: Lease<InstanceInfo> leaseToRenew = null; 6: if (gMap ! = null) { 7: leaseToRenew = gMap.get(id); If (leaseToRenew == null) {11: return false; 12: } else { 13: InstanceInfo instanceInfo = leaseToRenew.getHolder(); 14: if (instanceInfo ! 15: = null) {/ / to 16: application condition InstanceStatus overriddenInstanceStatus = this. GetOverriddenInstanceStatus (17: instanceInfo, leaseToRenew, isReplication); 19: if (overriddenInstanceStatus == InstanceStatus.UNKNOWN) {20: logger.info("Instance status UNKNOWN possibly due to deleted override for instance {}" 21: + "; re-register required", instanceInfo.getId()); 22: RENEW_NOT_FOUND.increment(isReplication); 23: return false; 24:} 25: // Set the application instance status. 26: if (! instanceInfo.getStatus().equals(overriddenInstanceStatus)) { 27: Object[] args = { 28: instanceInfo.getStatus().name(), 29: instanceInfo.getOverriddenStatus().name(), 30: instanceInfo.getId() 31: }; 32: logger.info( 33: "The instance status {} is different from overridden instance status {} for instance {}. " 34: + "Hence setting the status to overridden status", args); 35: instanceInfo.setStatusWithoutDirty(overriddenInstanceStatus); 36:} 37:} 38: // (omitted code) new lease renewal times per minute 39: // (omitted code) Set the last lease renewal time (renewed) 40: return true; 41:42:}}Copy the code
  • Lines 15 through 17: Get the final state of the application instance.
  • Lines 18 to 24: for the application instanceA final stateforUNKNOWN, unable to renew. returnfalseAfter that, the requester (eureka-client or other nodes in the Eureka-Server cluster) initiates the registrationEureka Source Code Analysis — Application Instance Registration Discovery (II) renewal of LeaseHave detailed analysis. Why is itUNKNOWN? in3. Interface for Deleting Application Instance Overwrite StatusPass the application instance status asUNKNOWN
  • Lines 25 to 36: Application instance status andA final stateNot equal, useA final stateOverrides the status of the application instance.Why is it not equal?#renew(...)#statusUpdate(...)Can be unlocked and executed in parallel if
    • #renew(...)After executing line 16, get theoverriddenInstanceStatusLater, happened to be#statusUpdate(...)The status of the application instance is updatednewStatus, and exactly the two are not equal, useoverriddenInstanceStatusOverrides the application instancenewStatusState.
    • Wouldn’t that be an overlay state (overriddenstatus) but covered?? No, in the next heartbeat, the state of the application instance will be corrected back. Of course, if the application instance state isUPorSTARTINGWill not be fixed, nor should it be.

4.4 Offline Scenario

// AbstractInstanceRegistry.java protected boolean internalCancel(String appName, String id, boolean isReplication) { // ... Omit irrelevant code / / removing applications cover mapping InstanceStatus InstanceStatus = overriddenInstanceStatusMap. Remove (id); if (instanceStatus ! = null) { logger.debug("Removed instance id {} from the overridden map which has value {}", id, instanceStatus.name()); }}Copy the code

4.5 Expiration Scenario

This section is the same as “4.4 Offline Scenario”.

5. The client invokes the interface

For application instance override state change and delete interface call, click the following method to view, very easy to understand, this article will not be worded:

666. The eggs

It takes a long time to guess the coverage state, and it takes a lot of brain cells to comb out the coverage rules of application instances.

Next, the Eureka-Server cluster moves in sync!

Fat friends, share my public number (impression channel source code) to your fat friends?