Eureka Server源码解析(服务主动下线流程)

本文深入解析了Eureka Server如何处理服务主动下线的源码,包括客户端发送删除请求、EurekaServer的InstanceResource.cancelLease方法、 PeerAwareInstanceRegistry的cancel方法以及内部的实例注册表变更、缓存清理和集群同步等关键步骤。通过源码分析,阐述了服务下线的具体操作和涉及的自我保护机制。
摘要由CSDN通过智能技术生成

原创不易,转载请注明出处

系列文章目录

  1. SpringCloud Eureka Server源码解析(启动流程)
  2. Eureka Server源码解析(服务注册流程)
  3. Eureka Server源码解析(服务续约流程)
  4. 深度解析Eureka的自我保护机制


前言

本文主要是解析下Eureka Server 处理客户端服务主动下线流程代码,服务主动下线其实很简单,就是客户端服务发送服务主动下线请求给Eureka Server ,Eureka Server 收到请求后将对应的实例信息从注册表中删除,删除本地多级缓存中关于该实例信息的数据,这样子服务发现的时候就不会被拉取到该实例的信息,最后就是将服务下线请求同步给Eureka Server 集群其他节点,接下来我们就看看Eureka Server 是怎样处理服务主动下线请求的。

1.源码解析

客户端服务delete请求/apps/{appName}/{instanceId} 路径到Eureka Server进行服务主动下线。
然后在Eureka Server 中InstanceResource 的cancelLease 方法接收服务下线请求并处理,我们看下

@DELETE
public Response cancelLease(
        @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
    boolean isSuccess = registry.cancel(app.getName(), id,
         "true".equals(isReplication));
         // 此处省略代码若干
    return Response.ok().build();
}

可以看到就是调用的注册表cancel进行服务主动下线,参数1:appName,参数2:instanceId 实例id, 参数3:是否是集群其他节点同步过来的。接下来我们就看下注册表PeerAwareInstanceRegistry 的cancel方法
PeerAwareInstanceRegistry #cancel

@Override
public boolean cancel(final String appName, final String id,
                      final boolean isReplication) {
    if (super.cancel(appName, id, isReplication)) {
        replicateToPeers(Action.Cancel, appName, id, null, null, isReplication);
        return true;
    }
    return false;
}

套路都是一样的,先是调用父类AbstractInstanceRegistry 的cancel 方法进行本地注册表变更,服务下线就是删除对应的服务实例信息。变更完本地服务注册表后,将服务主动下线请求同步给Eureka Server 集群的其他节点。
接下来我们看下本地注册表服务下线的流程。

@Override
public boolean cancel(String appName, String id, boolean isReplication) {
    return internalCancel(appName, id, isReplication);
}

这个internalCancel 方法内容比较多,我们分为几部分看看。
先是获取读写锁的读锁,其实在服务注册处理的那段代码也是获取读锁的。

// 获取appName 对应的所有实例集合
Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
Lease<InstanceInfo> leaseToCancel = null;
if (gMap != null) {
    // 根据实例id 移除对应的实例租约信息
    leaseToCancel = gMap.remove(id);
}

先是根据appName 从注册表中获取到对应的所有实例集合,也就是个map,然后根据实例id (instanceId) 从实例集合中移除对应实例的租约信息(服务信息)。

// 将变更信息 扔到最近删除队列中
recentCanceledQueue.add(new Pair<Long, String>(System.currentTimeMillis(), appName + "(" + id + ")"));
InstanceStatus instanceStatus = overriddenInstanceStatusMap.remove(id);

将要删除的appName+实例id 信息放入最近删除队列中,从实例状态map中移除该实例的状态信息。

// 变更实例剔除时间
leaseToCancel.cancel();
InstanceInfo instanceInfo = leaseToCancel.getHolder();
String vip = null;
String svip = null;
if (instanceInfo != null) {
instanceInfo.setActionType(ActionType.DELETED);
// 放入最近变更队列中
recentlyChangedQueue.add(new RecentlyChangedItem(leaseToCancel));
instanceInfo.setLastUpdatedTimestamp();
vip = instanceInfo.getVIPAddress();
svip = instanceInfo.getSecureVipAddress();
}
// 删除实例对应的缓存数据
invalidateCache(appName, vip, svip);

更新实例剔除时间, 删除该实例对应本地缓存数据。

// 更新 需要发送心跳的客户端数量
synchronized (lock) {
    if (this.expectedNumberOfClientsSendingRenews > 0) {
        // Since the client wants to cancel it, reduce the number of clients to send renews.
        this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews - 1;
        updateRenewsPerMinThreshold();
    }
}

更新需要发送续约信息客户端数量,毕竟是服务下线,就少了一个需要发送续约信息的客户端,更新自我保护机制触发阈值,这块涉及到Eureka Server 自我保护机制实现原理,感兴趣的小伙伴可以看下《深度解析Eureka的自我保护机制》 一文。
好了,到这服务主动下线的源码就解析完了。

2.流程图

在这里插入图片描述
高清大图:链接

总结

Eureka Server 处理服务主动下线主要是干了2件事,1是删除本地注册表中关于该实例的租约信息,删除本地多级缓存中关于该实例的信息;2是将服务下线请求同步给集群中的其他节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

$码出未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值