Eureka源码--服务端处理客户端注册

517 阅读3分钟

处理客户端请求

ApplicationResource注册方法

首先找到ApplicationResource类(专门处理请求的,这样的类还有其他的几个后面会介绍),里面有个addInstance方

   @POST
   @Consumes({"application/json", "application/xml"})
   public Response addInstance(InstanceInfo info,
   @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
     //省略instance的一些校验
     registry.register(info, "true".equals(isReplication));
     return Response.status(204).build();  // 204 to be backwards compatible
   }

PeerAwareInstanceRegistryImpl处理

调用PeerAwareInstanceRegistryImpl中的register方法

    public void register(final InstanceInfo info, final boolean isReplication) {
      //租期 默认是90s
      int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
      //传入的info的租约信息不为空并且租期大于0
      if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
        //设置成新的(传入的)租期
        leaseDuration = info.getLeaseInfo().getDurationInSecs();
      }
      //调用父类的register方法
      super.register(info, leaseDuration, isReplication);
      //复制到其他EurekaSever节点
      replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
    }

父类AbstractInstanceRegistry

调用父类的register方法也就是AbstractInstanceRegistry类中的register方法

   public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) {
     try {
       read.lock();
       //根据传入的实例id 获取该实例对应的租约信息
       Lease<InstanceInfo> existingLease = gMap.get(registrant.getId());
       // Retain the last dirty timestamp without overwriting it, if there is already a lease
       //注册的时候为什么为不为空呢?? 客户端信息修改之后 才会出现租约信息不为空的情况 
       if (existingLease != null && (existingLease.getHolder() != null)) {
         //服务端缓存中的时间戳
         Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp();
         //传入的实例的脏时间戳
         Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
         //正常情况下是不会大于的,主要是考虑网络因素引起的延迟,先改的后到了,
         if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) {
           registrant = existingLease.getHolder();
         }
       } else {
         // 租约信息不存在,表明这是一个新注册
         synchronized (lock) {
           //期望发送心跳租约的客户端数量  默认为1
           if (this.expectedNumberOfClientsSendingRenews > 0) {
             this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews + 1;
             //和自我保护机制有关,后续在进行说明
             updateRenewsPerMinThreshold();
           }
         }
       }
       Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration);
       if (existingLease != null) {
         lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
       }
       gMap.put(registrant.getId(), lease);
       // 如果instance的overridden状态不等于UNKNOWN 则表示overriddenInstanceStatusMap中应该会有对应的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());
         }
       }
       //获取instance的overriddenStatus
       InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId());
       if (overriddenStatusFromMap != null) {
         registrant.setOverriddenStatus(overriddenStatusFromMap);
       }
       // 根据overriddenStatus 和规则获取到 真正的status 并进行设置
     InstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease, isReplication);
       registrant.setStatusWithoutDirty(overriddenInstanceStatus);
       ....
     } finally {
       read.unlock();
     }
   }

Status处理规则

OverriddenInstanceStatus处理规则 getOverriddenInstanceStatus方法详解

Status值是注册表中真实的值,OverriddenInstanceStatus 则是更改的状态,status由OverriddenInstanceStatus推导出来

    //获取对应的规则
    InstanceStatusOverrideRule rule = getInstanceInfoOverrideRule();
    return rule.apply(r, existingLease, isReplication).status();
    //PeerAwareInstanceRegistryImpl中的方法
    protected InstanceStatusOverrideRule getInstanceInfoOverrideRule() {
         return this.instanceStatusOverrideRule;
    }
    //在PeerAwareInstanceRegistryImpl构造方法中对instanceStatusOverrideRule进行赋值
    this.instanceStatusOverrideRule = new FirstMatchWinsCompositeRule(new DownOrStartingRule(),
                    new OverrideExistsRule(overriddenInstanceStatusMap), new LeaseExistsRule());

最终会走到FirstMatchWinsCompositeRule中执行apply方法 在FirstMatchWinsCompositeRule构造器终会这设置上面传入的三种规则,以及一个默认的规则AlwaysMatchInstanceStatusRule

    //执行apply方法 根据传入的rule的顺序进行处理
    for (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);

DownOrStartingRule规则:只匹配状态为DOWN或者STARTING

OverrideExistsRule规则:判断overriddenInstanceStatusMap中是否包含该实例,如果包含说明更改过状态 要么是Up、要么是Out_Of_Service,如果匹配上则返回

LeaseExistsRule:如果上面不匹配(上线之后没有更改过状态 也就是overrideStatus为UNKNOWN)。如果原有租约信息不为空,并且状态为UP或者Out_Of_Service才能匹配上