了解Spring Cloud Eureka Server的自我保存和续订阈值


82

我已经开始开发微服务,尽管我已经研究了一段时间,同时阅读了Spring的文档和Netflix的文档。

我已经开始在Github上进行一个简单的项目。它基本上是一个Eureka服务器(Archimedes)和三个Eureka客户端微服务(一个公共API和两个私有)。查看github的自述文件以获取详细描述。

关键是,当一切都在运行时,我希望如果其中一个私有微服务被杀死,Eureka服务器会意识到这一点并将其从注册表中删除。

在Stackoverflow上发现了这个问题,该解决方案通过enableSelfPreservation:false在Eureka Server配置中使用而得以通过。一段时间后,被取消的服务会按预期消失。

但是我可以看到以下消息:

自我保存模式已关闭。在网络/其他问题的情况下,此设置可能无法保护即时实例。

1.自我保存的目的是什么?该文档指出,通过自我保留,“客户端可以获取不再存在的实例”。那么什么时候建议打开/关闭它呢?

此外,打开自我保存功能后,您可能会在Eureka Server控制台中收到一条警告消息:

紧急!如果不是,EUREKA可能会不正确地提出索赔要求。续订比阈值要少,因此不再只是为了安全起见而立即终止实例。

现在,继续使用Spring Eureka Console。

Lease expiration enabled    true/false
Renews threshold    5
Renews (last min)   4

我遇到了阈值计数的怪异行为:当我单独启动Eureka Server时,阈值为1。

2.我有一台Eureka服务器,并且配置registerWithEureka: false为防止它在另一台服务器上注册。那么,为什么它会显示在阈值计数中?

3.对于我启动的每个客户,阈值计数都会增加+2。我猜是因为它们每分钟发送2条更新消息,对吗?

4. Eureka服务器从不发送续订,因此最后一次续订始终低于阈值。这正常吗?

renew threshold 5
rewnews last min: (client1) +2 + (client2) +2 -> 4

服务器cfg:

server:
  port: ${PORT:8761}

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enableSelfPreservation: false
#   waitTimeInMsWhenSyncEmpty: 0

客户端1 cfg:

spring:
  application:
    name: random-image-microservice

server:
  port: 9999

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    healthcheck:
      enabled: true

3
我想花时间回答这个问题。情况很复杂。一些答案在Netflix代码中,其他答案在配置中。我希望我的答案最终成为Spring Cloud文档的一部分,但是除非感恩节之前的同事回答,否则可能是在感恩节之后。
spencergibb

这是Netflix的一些背景知识:github.com/Netflix/eureka/wiki/…–
spencergibb


8
@spencergibb,这已经接近9个月了,没有答案..有什么投入吗?
尼克

1
@spencergibb现在已经一年多了。仍有机会随时获得明确答案吗?某种圣诞节礼物:)
OcuS

Answers:


62

我遇到的问题与@codependent遇到的问题相同,我在Google上搜索了很多并进行了一些实验,在这里我来提供一些有关Eureka服务器和实例如何工作的知识。

每个实例都需要以每30秒1次的频率将其租约续签到Eureka Server,可以在中定义eureka.instance.leaseRenewalIntervalInSeconds

更新(最后一分钟):表示在最后一分钟从尤里卡实例收到的更新数

续订阈值:Eureka服务器期望每分钟从Eureka实例收到的续订。

例如,如果registerWithEureka将if设置为falseeureka.instance.leaseRenewalIntervalInSeconds则将其设置为30并运行2个Eureka实例。两个Eureka实例每分钟将向Eureka服务器发送4个续订,Eureka服务器的最小阈值为1(用代码编写),因此阈值为5(此数字将乘以一个因子eureka.server.renewalPercentThreshold,稍后将进行讨论)。

自保存模式:如果“续订”(最后一个分钟)小于“续订”阈值,则将激活自保存模式。

因此在上例中,由于阈值为5,所以激活了SELF PRESERVATION MODE,但是Eureka服务器每分钟只能接收4次更新。

  1. 问题1:

“自我保护模式”旨在避免不良的网络连接失败。Eureka实例A和B之间的连通性很好,但是B由于连接中断而未能在短时间内将其租约续签到Eureka服务器,此时Eureka服务器不能简单地将实例B踢出去。尽管B可用,但A不会从Eureka服务器获得可用的注册服务。因此,这是自保存模式的目的,最好将其打开。

  1. 问题2:

最小阈值1写入代码中。registerWithEureka设置为false,因此将没有Eureka实例寄存器,阈值为1。

在生产环境中,通常我们部署两个Eureka服务器,registerWithEureka并将其设置为true。因此,阈值将为2,Eureka服务器将每分钟两次向其自身续订租约,因此RENEWALS ARE LESSER THAN THRESHOLD不会有问题。

  1. 问题3:

你是对的。eureka.instance.leaseRenewalIntervalInSeconds定义每分钟发送给服务器的续订数量,但是它将乘以上述系数eureka.server.renewalPercentThreshold,默认值为0.85。

  1. 问题4:

是的,这很正常,因为阈值初始值设置为1。因此,如果registerWithEureka将其设置为false,则续订始终低于阈值。

我对此有两个建议:

  1. 部署两个Eureka服务器并启用registerWithEureka
  2. 如果只想在演示/开发环境中进行部署,则可以将其设置eureka.server.renewalPercentThreshold为0.49,因此,当单独启动Eureka服务器时,阈值将为0。

嗨,聂星,您知道标签的含义是什么:“启用租赁到期:”
jabrena

@jabrena,您好,我认为如果实例不将其租约续签到eureka服务器,则租约将到期。它可能与eureka.instance.leaseExpirationDurationInSeconds有关,默认值为90秒。如果将此值设置为0或负数,则标签可能会变为“已启用租赁到期:False”。您可以尝试一下。
聂行


不起作用 阈值= 0,更新= 0仍会触发警告。
SledgeHammer

我禁用了selfPreservationMode,但仍然在Eureka上收到此消息-EUREKA可能不正确地要求提供实例,而如果不是这样的话。续订比阈值要少,因此仅出于安全性考虑,实例不会过期。它不应该发生吧?
DHRUV BANSAL

31

我在此处创建了一个包含Eureka详细信息的博客文章,该文章填补了Spring文档或Netflix博客中缺少的一些细节。这是经过几天调试和挖掘源代码的结果。我知道复制粘贴比链接到外部URL更可取,但是对于SO答案来说,内容太大了。


2
感谢您链接这样的澄清帖子。推荐阅读!
codepend

2
@Abhijit Sarkar,您好,这篇文章很棒。我解决了许多配置方面的疑问。
jabrena

0

您可以尝试在eureka服务器属性中设置续订阈值限制。如果您要在eureka上注册大约3至4个微服务,则可以将其设置为:

eureka.server.renewalPercentThreshold=0.33
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.