尤里卡的自我保护模式永远不会恢复

Posted

技术标签:

【中文标题】尤里卡的自我保护模式永远不会恢复【英文标题】:Eureka's self-preservation mode never recovers 【发布时间】:2016-01-14 01:20:11 【问题描述】:

我目前面临一个问题,即 Eureka 永远不会清除由于虚拟机意外停机而变得陈旧的服务实例。可以理解的是,Eureka 的自我保护模式启动了,因为服务更新/心跳请求大幅下降(低于阈值)。然而,15 个多小时后,死亡的实例仍然在 Eureka 中注册。这是一个主要问题,因为服务请求继续被定向到死实例,只是为了返回错误。

我希望阈值不断调整,一段时间后,尤里卡的阈值会达到一个新的标准水平,自我保护模式会被重置。我们在镜像设置中使用 Eureka,我们的配置不是很复杂。

我们的设置:

Eureka 通过 spring-boot-starter-parent 1.2.5.RELEASE

eureka:
  dashboard:
    path: services
    enabled: false
  instance:
    hostname: localhost
    leaseRenewalIntervalInSeconds: 3
    metadataMap:
      managementPath: /admin
      instanceId: discoveryPrimary
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://$eureka.instance.hostname:$server.port/eureka/
  server:
    waitTimeInMsWhenSyncEmpty: 0

是否可以调整 Eureka 配置以重置自我保存模式(它停止清除实例)并允许它在服务停止 5 分钟以上时清除服务注册表?

【问题讨论】:

【参考方案1】:

如果您只有几个服务实例,那么每次其中任何一个失败时,自我保护都会启动,因为默认情况下renewalPercentThreshold0.85

因此,如果只有 84% 的实例续订租约,尤里卡“开启”自我保护。

这意味着,如果您有 3 个实例并且一个失败,则只有 66% 的实例更新了许可证,因此没有一个实例会被取消注册。您可以在服务器属性中调整 renewalPercentThreshold 以适应您的部署。

eureka:
  server:
    renewalPercentThreshold: 0.49

有了这个,如果你有 2 个实例并且 1 个失败,你仍然很好。

【讨论】:

调整renewalPercentThreshold将通过延迟自我保存模式来解决这个问题。我们可以通过设置eureka.server.enableSelfPreservation=false 来完成相同的操作,但是如果触发了自我保护并且这些实例永远不会回来,这仍然无法解决问题。 不,如果您的网络健康,或者您的实例不是每分钟都来来去去,它不仅会延迟自我保护模式。它只是为较小的基础架构配置的。您可以使用renewalThresholdUpdateIntervalMs 进一步调整它,这样自我保护的时间窗口就会更小。如果您将其关闭,您根本就不会使用 Eureka 的弹性功能之一。 我们的目标是尝试使用 Eureka 的所有弹性功能,包括自我保护模式。但是,通过将阈值设置得较低,它只会避免启用自我保护模式,并且一旦启用,它仍然不会在 15+ 小时后清除死亡实例。由于上述原因,我不认为阈值是问题。是否有其他一些配置可以让自我保护模式重置并最终清除死实例?【参考方案2】:

即使是老问题,这是我的两分钱。

我希望阈值不断调整,经过一段时间 在一段时间内,Eureka 的门槛将处于新的规范水平,并且 自我保护模式将被重置。

不正确的假设。 Eureka 自我保护永不过期,阈值也不会动态调整。您必须恢复关闭的虚拟机/客户端(以便总体上 > 85% 的客户端处于启动状态)才能摆脱这种状态。

我认为关闭它是有意义的 - 看看 conclusions here 和类似的 question here。

【讨论】:

不建议在生产中禁用自我保存模式。从注册表中删除一个丢失的心跳和一个健康的实例。不是个好主意。 你不正确@narendra-choudhary。一个错过的心跳不会驱逐一个实例。如果心跳失败,客户端会以 2 倍指数方式后退,直到最大延迟。然后回退到服务器列表中的下一个服务器,服务器复制注册表信息。【参考方案3】:

按照@Fahim Farook 的回答建议禁用此模式后,为避免丢失一个心跳导致注册表被删除,您可以通过配置以下属性来调整可接受的丢失心跳持续时间:

eureka.instance.lease-renewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=180

【讨论】:

以上是关于尤里卡的自我保护模式永远不会恢复的主要内容,如果未能解决你的问题,请参考以下文章

《SpringCloud超级入门》Eureka自我保护模式和InstanceID的配置《十四》

3.1 eureka自我保护

Spring Cloud Eureka的自我保护模式与实例下线剔除

springCloud:Eureka的自我保护模式多网卡下的IP选择Eureka的健康检查

了解 Eureka 客户端缓存

Spring Cloud系列教程第九篇-Eureka自我保护机制