服务注册接口源码分析:

com.netflix.eureka.resources.ApplicationResource#addInstance

public Response addInstance(InstanceInfo info,
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
//注册
registry.register(info, "true".equals(isReplication));
return Response.status(204).build(); // 204 to be backwards compatible
}

com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#register

public void register(final InstanceInfo info, final boolean isReplication) {
// 心跳检测周期默认90s
int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
// 配置文件设置该时间,就用配置文件的设置时间
if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
leaseDuration = info.getLeaseInfo().getDurationInSecs();
}
// 调用父方法
super.register(info, leaseDuration, isReplication);
// 复制到集群其他节点
replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
}

com.netflix.eureka.registry.AbstractInstanceRegistry#register

public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) {
try {
read.lock();
// 从注册表中获取实例信息
Map<String, Lease<InstanceInfo>> gMap = registry.get(registrant.getAppName());
REGISTER.increment(isReplication);
// 第一次注册时,gMap是null
if (gMap == null) {
// 定义一个Map
final ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap = new ConcurrentHashMap<String, Lease<InstanceInfo>>();
// 进行put操作
gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
if (gMap == null) {
gMap = gNewMap;
}
}
// 根据实例ID获取注册信息,第一次注册获取为空
Lease<InstanceInfo> existingLease = gMap.get(registrant.getId());
// 不为空,说明已注册但实例信息发生变化
if (existingLease != null && (existingLease.getHolder() != null)) {
Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp();
Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
logger.debug("Existing lease found (existing={}, provided={}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp); //
if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) {
logger.warn("There is an existing lease and the existing lease's dirty timestamp {} is greater" +
" than the one that is being registered {}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp);
logger.warn("Using the existing instanceInfo instead of the new instanceInfo as the registrant");
registrant = existingLease.getHolder();
}
} else {
// 该租约不存在,因此它是一个新的注册
synchronized (lock) {
if (this.expectedNumberOfClientsSendingRenews > 0) {
// 因为客户机想要注册它,所以要增加发送更新的客户机的数量
this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews + 1;
updateRenewsPerMinThreshold();
}
}
logger.debug("No previous lease information found; it is new registration");
}
Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration);
if (existingLease != null) {
lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
}
// 将实例信息加入map中
gMap.put(registrant.getId(), lease);
synchronized (recentRegisteredQueue) {
recentRegisteredQueue.add(new Pair<Long, String>(
System.currentTimeMillis(),
registrant.getAppName() + "(" + registrant.getId() + ")"));
}
// 更新状态信息
if (!InstanceStatus.UNKNOWN.equals(registrant.getOverriddenStatus())) {
logger.debug("Found overridden status {} for instance {}. Checking to see if needs to be add to the "
+ "overrides", registrant.getOverriddenStatus(), registrant.getId());
if (!overriddenInstanceStatusMap.containsKey(registrant.getId())) {
logger.info("Not found overridden id {} and hence adding it", registrant.getId());
overriddenInstanceStatusMap.put(registrant.getId(), registrant.getOverriddenStatus());
}
}
InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId());
if (overriddenStatusFromMap != null) {
logger.info("Storing overridden status {} from map", overriddenStatusFromMap);
registrant.setOverriddenStatus(overriddenStatusFromMap);
} InstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease, isReplication);
registrant.setStatusWithoutDirty(overriddenInstanceStatus); if (InstanceStatus.UP.equals(registrant.getStatus())) {
lease.serviceUp();
}
registrant.setActionType(ActionType.ADDED);
recentlyChangedQueue.add(new RecentlyChangedItem(lease));
registrant.setLastUpdatedTimestamp();
invalidateCache(registrant.getAppName(), registrant.getVIPAddress(), registrant.getSecureVipAddress());
logger.info("Registered instance {}/{} with status {} (replication={})",
registrant.getAppName(), registrant.getId(), registrant.getStatus(), isReplication);
} finally {
read.unlock();
}
}

com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#replicateToPeers

将注册信息同步到集群中其他节点

private void replicateToPeers(Action action, String appName, String id,
InstanceInfo info /* optional */,
InstanceStatus newStatus /* optional */, boolean isReplication) {
Stopwatch tracer = action.getTimer().start();
try {
if (isReplication) {
numberOfReplicationsLastMin.increment();
}
// 如果它已经是一个复制,不要再次复制
if (peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
return;
} for (final PeerEurekaNode node : peerEurekaNodes.getPeerEurekaNodes()) {
// 如果url表示此主机,则不要复制到自己.
if (peerEurekaNodes.isThisMyUrl(node.getServiceUrl())) {
continue;
}
// 复制操作
replicateInstanceActionsToPeers(action, appName, id, info, newStatus, node);
}
} finally {
tracer.stop();
}
}

com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#replicateInstanceActionsToPeers

复制操作

private void replicateInstanceActionsToPeers(Action action, String appName,
String id, InstanceInfo info, InstanceStatus newStatus,
PeerEurekaNode node) {
try {
InstanceInfo infoFromRegistry = null;
CurrentRequestVersion.set(Version.V2);
switch (action) {
case Cancel: // 下线
node.cancel(appName, id);
break;
case Heartbeat://心跳
InstanceStatus overriddenStatus = overriddenInstanceStatusMap.get(id);
infoFromRegistry = getInstanceByAppAndId(appName, id, false);
node.heartbeat(appName, id, infoFromRegistry, overriddenStatus, false);
break;
case Register://注册
node.register(info);
break;
case StatusUpdate:// 状态更新
infoFromRegistry = getInstanceByAppAndId(appName, id, false);
node.statusUpdate(appName, id, newStatus, infoFromRegistry);
break;
case DeleteStatusOverride:
infoFromRegistry = getInstanceByAppAndId(appName, id, false);
node.deleteStatusOverride(appName, id, infoFromRegistry);
break;
}
} catch (Throwable t) {
logger.error("Cannot replicate information to {} for action {}", node.getServiceUrl(), action.name(), t);
}
}

最新文章

  1. C#多线程--线程池(ThreadPool)
  2. MYSQL操作数据表中的记录
  3. java识别简单的验证码
  4. 常用PHP运行环境一键安装包
  5. access 导数据到sql server 2008
  6. Cloud Foundry中gorouter对StickySession的支持
  7. 深入浅出Node.js (附录A) - 安装Node
  8. MySQL多表查询之外键、表连接、子查询、索引
  9. linux禁用锁定和解除解锁用户账号的方法
  10. 使用JSONP实现跨域
  11. python如何转换word格式、读取word内容、转成html
  12. hive动态分区和混合分区
  13. js之添加浏览器历史记录
  14. 如何用 Java 实现 Web 应用中的定时任务?
  15. 探寻main函数的“标准”写法,以及获取main函数的参数、返回值
  16. C语言 一些算法
  17. Android之ProGuard混淆器
  18. C++开学第一次作业(5.4)
  19. rn打包分析
  20. BZOJ3675 [Apio2014]序列分割 【斜率优化dp】

热门文章

  1. 穿透的switch语句-循环概述与基本组成部分
  2. Python TensorFlow深度学习回归代码:DNNRegressor
  3. pycharm设置python头文件模版
  4. python正则分组匹配
  5. Django-Django基本使用、app、三板斧
  6. Jpbc哈希函数如何实现
  7. 学习Java Day20
  8. 下篇 | 使用 &#129303; Transformers 进行概率时间序列预测
  9. 图论之最短路径Dijkstra算法
  10. Docker安装部署Mysql8(以作数据持久化)