Process client requests

ApplicationResource registration method

Start by finding the ApplicationResource class (which specializes in handling requests, and there are several others that will be described later), which has the addInstance method

   @POST
   @Consumes({"application/json", "application/xml"})
   public Response addInstance(InstanceInfo info,
   @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
     // omit some validation of instance
     registry.register(info, "true".equals(isReplication));
     return Response.status(204).build();  // 204 to be backwards compatible
   }
Copy the code

PeerAwareInstanceRegistryImpl processing

Call register of PeerAwareInstanceRegistryImpl method

    public void register(final InstanceInfo info, final boolean isReplication) {
      // The default lease is 90s
      int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
      // The lease information passed to info is not empty and the lease is greater than 0
      if(info.getLeaseInfo() ! =null && info.getLeaseInfo().getDurationInSecs() > 0) {
        // Set to the new (incoming) lease term
        leaseDuration = info.getLeaseInfo().getDurationInSecs();
      }
      // Call the parent register method
      super.register(info, leaseDuration, isReplication);
      // Copy to other EurekaSever nodes
      replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
    }
Copy the code

The parent class AbstractInstanceRegistry

Call the register method of the parent class, that is, the Register method of the AbstractInstanceRegistry class

   public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) {
     try {
       read.lock();
       // Get the lease information for the instance based on the instance ID passed in
       Lease<InstanceInfo> existingLease = gMap.get(registrant.getId());
       // Retain the last dirty timestamp without overwriting it, if there is already a lease
       // Why not empty when registering?? The lease information is not empty only after the client information is modified
       if(existingLease ! =null&& (existingLease.getHolder() ! =null)) {
         // Timestamp in server cache
         Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp();
         // The dirty timestamp of the passed instance
         Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
         // In normal case, it will not be larger than that, mainly because of the delay caused by network factors.
         if(existingLastDirtyTimestamp > registrationLastDirtyTimestamp) { registrant = existingLease.getHolder(); }}else {
         // Lease information does not exist, indicating a new registration
         synchronized (lock) {
           // The number of clients expected to send heartbeat leases is 1 by default
           if (this.expectedNumberOfClientsSendingRenews > 0) {
             this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews + 1;
             // It has to do with self-protection mechanisms, which will be explained later
             updateRenewsPerMinThreshold();
           }
         }
       }
       Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration);
       if(existingLease ! =null) {
         lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
       }
       gMap.put(registrant.getId(), lease);
       / / if the instance overridden state is not equal to UNKNOWN said overriddenInstanceStatusMap should have corresponding status value
       // Status :UP, DOWN, STARTING, OUT_OF_SERVICE, UNKNOWN
       if(! InstanceStatus.UNKNOWN.equals(registrant.getOverriddenStatus())) {if (!overriddenInstanceStatusMap.containsKey(registrant.getId())) {
           overriddenInstanceStatusMap.put(registrant.getId(), registrant.getOverriddenStatus());
         }
       }
       // Get the overriddenStatus of instance
       InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId());
       if(overriddenStatusFromMap ! =null) {
         registrant.setOverriddenStatus(overriddenStatusFromMap);
       }
       // Get the real status according to the overriddenStatus and rules and set itInstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease, isReplication); registrant.setStatusWithoutDirty(overriddenInstanceStatus); . }finally{ read.unlock(); }}Copy the code

Status Processing rule

OverriddenInstanceStatus processing rules, rounding getOverriddenInstanceStatus method

The Status value is the actual value in the registry, and OverriddenInstanceStatus is the changed state, which is derived from OverriddenInstanceStatus

    // Get the corresponding rule
    InstanceStatusOverrideRule rule = getInstanceInfoOverrideRule();
    return rule.apply(r, existingLease, isReplication).status();
    / / the PeerAwareInstanceRegistryImpl method
    protected InstanceStatusOverrideRule getInstanceInfoOverrideRule(a) {
         return this.instanceStatusOverrideRule;
    }
    / / in PeerAwareInstanceRegistryImpl construction method for assignment instanceStatusOverrideRule
    this.instanceStatusOverrideRule = new FirstMatchWinsCompositeRule(new DownOrStartingRule(),
                    new OverrideExistsRule(overriddenInstanceStatusMap), new LeaseExistsRule());
Copy the code

Will eventually go FirstMatchWinsCompositeRule that executes the apply method in FirstMatchWinsCompositeRule constructor will be that the three rules of the incoming set above And a default rules AlwaysMatchInstanceStatusRule

    // The apply method is applied according to the order in which the rules are passed in
    for (int i = 0; i < this.rules.length; ++i) {
         StatusOverrideResult result = this.rules[i].apply(instanceInfo, existingLease, isReplication);
         if (result.matches())  return result;   
     }
    // If none of the three passed rules matches, the default rule that always matches is used for processing
    return defaultRule.apply(instanceInfo, existingLease, isReplication);
Copy the code

DownOrStartingRule Rule: Matches only the DOWN or STARTING state

OverrideExistsRule rule: judging whether overriddenInstanceStatusMap contains the instance, if you include instructions changed state Either the Up or Out_Of_Service, if the match is returned

LeaseExistsRule: If the above does not match (overrideStatus is UNKNOWN if the status has not changed since being online). Only if the original lease information is not empty and the state is UP or Out_Of_Service, can a match be found