当Eureka实例在关闭自我保护的Eureka服务器上跳过心跳时会发生什么?

时间:2018-03-06 10:49:41

标签: spring-cloud netflix-eureka spring-cloud-netflix

考虑这个设置:

  • 已禁用自我保护模式的Eureka服务器,即enableSelfPreservation: false
  • 2个Eureka实例,每个实例有2个服务(比如服务#1和服务#2)。总共4个实例。

其中一个实例(比如srv#1inst#1,服务#1的实例)发送了一个心跳,但它没有到达Eureka服务器

AFAIK,在服务器端按顺序执行以下操作:

  • ServerStep1:服务器观察到特定实例错过了心跳。
  • ServerStep2:Server标记要驱逐的实例。
  • ServerStep3:服务器的驱逐调度程序(定期运行)从注册表中驱逐实例。

现在在实例(srv#1inst#1)方面:

  • InstanceStep1:跳过心跳。
  • InstanceStep2:它意识到心跳没有到达Eureka Server。它以指数后退重试。

AFAIK,驱逐和登记不会立即发生。 Eureka服务器定期为两个任务运行单独的调度程序。

我有一些与此过程相关的问题:

  • 序列是否正确?如果没有,我错过了什么?
  • 关于驱逐和登记调度程序的假设是否正确?
  • 服务#2的实例在ServerStep2之后立即从服务器请求新的注册表副本。
    • srv#1inst#1是否在新的注册表副本中,因为它还没有被驱逐?
      • 如果是,srv#1inst#1会被标记为UP还是DOWN?
  • 来自srv#1inst#1的InstanceStep2的重试请求在ServerStep2之后立即到达服务器。
    • 注册表会立即发生变化吗?
    • 这将如何影响服务#2对新注册表的请求的响应?它将如何影响驱逐调度程序?

1 个答案:

答案 0 :(得分:0)

qiangdavidliu中的one of the issues of eureka's GitHub repository回答了这个问题。

为了完整性,我在这里添加他的解释。


在我具体回答问题之前,这是有关心跳和逐出的一些高级信息(基于默认配置):

  1. 实例连续错过3次心跳才被驱逐
  2. (大多数)心跳不会重试,它们每30秒会尽力而为。心跳将重试的唯一时间是,如果心跳线程上存在线程级错误(即TimeoutRejectedExecution),但这应该非常少。

让我尝试回答您的问题:

序列正确吗?如果没有,我想念什么?

A:经过上述说明,序列是正确的。

关于驱逐和注册计划程序的假设是否正确?

A:逐出由内部调度程序处理。注册由处理程序线程处理以进行注册请求。

服务#2的实例在ServerStep2之后立即向服务器请求新的注册表副本。

  • 将srv#1inst#1保留在新的注册表副本中,因为尚未将其逐出吗?
    • 如果是,将srv#1inst#1标记为UP还是DOWN?

A:这里有几件事:

  1. 直到实例被真正驱逐,这将是结果的一部分
  2. 驱逐不涉及更改实例状态,而只是从注册表中删除实例
  3. 该服务器拥有30多个世界状态的缓存,并且正是此缓存被返回。因此,在逐出方案中,客户端所看到的确切结果仍然取决于它何时属于缓存的更新周期。

来自srv#1inst#1的InstanceStep2的重试请求在ServerStep2之后立即到达服务器。

  • 注册表会立即更改吗?
  • 这将如何影响对service#2请求新注册表的响应?它将如何影响驱逐调度程序?

A:再说几件事:

  1. 当实际驱逐发生时,我们检查每个被驱逐者的时间,以查看是否有资格被驱逐。如果实例能够在此事件之前更新其心跳,则它不再是驱逐的目标。
  2. 所讨论的3个事件(在驱逐时评估驱逐资格,更新实例的心跳状态,生成要返回读操作的结果)都是异步发生的,它们的结果将取决于对事件的评估。执行时达到上述条件。