概述
服务续约的作用
所谓的续约,其实不过一种健康检查的叫法,就是客户端告诉服务器端,我还活着。无论是zookeeper,nacos,eureka,还是各种监控系统,都存在着向服务器发送特殊信息标识自己依然存活,避免被剔除的命运。
服务续约
基于第七篇中注册接口的寻找方法,我们可以在Resource类中找到com.netflix.eureka.resources.InstanceResource#renewLease
续约接口
1.续约接口基本解析
通过下面一顿注解可以发现,主要在做两件事:
1.交给org.springframework.cloud.netflix.eureka.server.InstanceRegistry#renew继续进行续约操作
2.检查客户端传递的上次更新时间戳和服务器的时间戳是否不同(续约失败,同步失败,更新失败等造成)
public Response renewLease(
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,
@QueryParam("overriddenstatus") String overriddenStatus,
@QueryParam("status") String status,
@QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {
// 1.是不是从其他节点复制过来的续约信息
boolean isFromReplicaNode = "true".equals(isReplication);
// 2.交给InstanceRegistry进一步注册
boolean isSuccess = registry.renew(app.getName(), id, isFromReplicaNode);
// 如果没有在注册表中找到注册信息,立刻返回未找到
// Not found in the registry, immediately ask for a register
if (!isSuccess) {
logger.warn("Not Found (Renew): {} - {}", app.getName(), id);
return Response.status(Status.NOT_FOUND).build();
}
// Check if we need to sync based on dirty time stamp, the client
// instance might have changed some value
Response response;
//当上次更新时间跟本地注册表的时间不一致的时候,需要同步状态
if (lastDirtyTimestamp != null && serverConfig.shouldSyncWhenTimestampDiffers()) {
// 客户端传入的上次更新时间和服务器存储的时间不一致时进行处理
response = this.validateDirtyTimestamp(Long.valueOf(lastDirtyTimestamp), isFromReplicaNode);
// Store the overridden status since the validation found out the node that replicates wins
// 当renew传入的上次客户端更新时间大于注册表中的上次更新时间时,表示中间存在未同步或者同步失败操作
// 这时候需要同步客户端状态信息
if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()
&& (overriddenStatus != null)
&& !(InstanceStatus.UNKNOWN.name().equals(overriddenStatus))
&& isFromReplicaNode) {
// 状态同步,用传入的状态覆写现在机器的状态
registry.storeOverriddenStatusIfRequired(app.getAppName(), id, InstanceStatus.valueOf(overriddenStatus));
}
} else {
response = Response.ok().build();
}
logger.debug("Found (Renew): {} - {}; reply status={}", app.getName(), id, response.getStatus());
return response;
}
2.InstanceRegistry的renew之事件推送
在InstanceRegistry中做了个事件推送后,继续交给父类去renew
3.InstanceRegistry的父类之节点同步
在com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#renew
中,再次将续约交给父类,自己做了个服务器集群节点复制
4.AbstractInstanceRegistry之正在的续约
在com.netflix.eureka.registry.AbstractInstanceRegistry#renew
进行真正的注册,下面通过分析源码,总结大致流程:
1.从注册表中获取同服务名的集群信息,从集群中拿取续约实例
2.检查实例状态,更新续约检查时间
public boolean renew(String appName, String id, boolean isReplication) {
RENEW.increment(isReplication);
//1.通过应用名,从注册表中取出该应用的集群map信息
Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
Lease<InstanceInfo> leaseToRenew = null;
if (gMap != null) {
// 根据实例ID 从集群map中获取该实例的续约对象
leaseToRenew = gMap.get(id);
}
if (leaseToRenew == null) {
// 过来续约,发现注册表中已不存在该实例信息(发生在失效剔除,同步失败等情况下)
RENEW_NOT_FOUND.increment(isReplication);
logger.warn("DS: Registry: lease doesn't exist, registering resource: {} - {}", appName, id);
return false;
} else {
InstanceInfo instanceInfo = leaseToRenew.getHolder();
if (instanceInfo != null) {
// touchASGCache(instanceInfo.getASGName());
// 覆写实例状态
InstanceStatus overriddenInstanceStatus = this.getOverriddenInstanceStatus(
instanceInfo, leaseToRenew, isReplication);
if (overriddenInstanceStatus == InstanceStatus.UNKNOWN) {
logger.info("Instance status UNKNOWN possibly due to deleted override for instance {}"
+ "; re-register required", instanceInfo.getId());
RENEW_NOT_FOUND.increment(isReplication);
return false;
}
// 如果服务器存储的实例信息的状态和续约接口传递过来的状态不一致时
// 那么就需要同步实例状态了
if (!instanceInfo.getStatus().equals(overriddenInstanceStatus)) {
logger.info(
"The instance status {} is different from overridden instance status {} for instance {}. "
+ "Hence setting the status to overridden status", instanceInfo.getStatus().name(),
instanceInfo.getOverriddenStatus().name(),
instanceInfo.getId());
instanceInfo.setStatusWithoutDirty(overriddenInstanceStatus);
}
}
renewsLastMin.increment();
// 更新下次续约检查最后时间
leaseToRenew.renew();
return true;
}
}
总结
续约的过程比较简单,就是去更新InstanceInfo中的lastUpdateTimestamp。当然客户端状态还是要检查更新一下的。其流程基本跟注册一致。
到这里基本再去跟踪服务器端其他接口也就雷同了,后面不再花篇幅进行分析。
下面我们将进入Eureka客户端视角进行源码解读。
难的是开始,贵的是坚持,最后发现全是收获
最后
以上就是可靠汉堡为你收集整理的SpringCloud-Eureka服务端之续约接口(8)的全部内容,希望文章能够帮你解决SpringCloud-Eureka服务端之续约接口(8)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复