处理客户端请求
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才能匹配上