服務下架
如上圖所示一路debug走InstanceRegistry(發佈事件)——>AbstractInstanceRegistry(真正操作)——>PeerAwareInstanceRegistryImpl(集羣同步),設計採取責任鏈模式遵循單一職責原則.
InstanceResource #cancelLease()
——>InstanceRegistry#cancel發佈事件EurekaInstanceCanceledEvent
——>AbstractInstanceRegistry#cancel 真正進行服務下架操作
——>PeerAwareInstanceRegistryImpl#cancel 集羣同步
真正進行服務下架操作
protected boolean internalCancel(String appName, String id, boolean isReplication) {
try {
read.lock();
CANCEL.increment(isReplication);
//從registry拿到appName的微服務組
Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
Lease<InstanceInfo> leaseToCancel = null;
if (gMap != null) {
//從appName的微服務組拿到id的微服務實例
leaseToCancel = gMap.remove(id);
}
synchronized (recentCanceledQueue) {
//最近下架的微服務的queue
recentCanceledQueue.add(new Pair<Long, String>(System.currentTimeMillis(), appName + "(" + id + ")"));
}
InstanceStatus instanceStatus = overriddenInstanceStatusMap.remove(id);
if (instanceStatus != null) {
logger.debug("Removed instance id {} from the overridden map which has value {}", id, instanceStatus.name());
}
if (leaseToCancel == null) {
//下架失敗
CANCEL_NOT_FOUND.increment(isReplication);
logger.warn("DS: Registry: cancel failed because Lease is not registered for: {}/{}", appName, id);
return false;
} else {
//調用lease的cancel記錄evictionTimestamp
leaseToCancel.cancel();
//微服務實例
InstanceInfo instanceInfo = leaseToCancel.getHolder();
String vip = null;
String svip = null;
if (instanceInfo != null) {
//設置微服務狀態delete
instanceInfo.setActionType(ActionType.DELETED);
//近三分鐘發生改動的微服務的queue,用於增量更新使用返回給客戶端
recentlyChangedQueue.add(new RecentlyChangedItem(leaseToCancel));
//最後更新的時間戳
instanceInfo.setLastUpdatedTimestamp();
vip = instanceInfo.getVIPAddress();
svip = instanceInfo.getSecureVipAddress();
}
// 更新緩存數據
invalidateCache(appName, vip, svip);
logger.info("Cancelled instance {}/{} (replication={})", appName, id, isReplication);
return true;
}
} finally {
read.unlock();
}
}
服務續期
一樣是發佈事件,續期操作,集羣同步,這裏只看續期最低層方法renew
public boolean renew(String appName, String id, boolean isReplication) {
RENEW.increment(isReplication);
//從registry拿到appName的微服務組
Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
Lease<InstanceInfo> leaseToRenew = null;
if (gMap != null) {
//從appName的微服務組拿到id的微服務實例
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();
//執行lease的renew進行續期
leaseToRenew.renew();
return true;
}
}
總結
服務下架:發佈下架事件,下架操作gMap.remove,lease.cancel, 集羣同步
服務續期:發佈續期事件,續期操作lease.renew,集羣同步