《Spring Cloud 》Eureka服务调用服务超时重试机制

《Spring Cloud 》Eureka服务调用服务超时重试机制,第1张

问题根源有二:

1):业务耗时时间比较长,超过服务调用超时时间配置,由于Spring Cloud 服务调用超时重试机制默认开启,所以会导致服务被调用了两次。

2):服务端未做幂等性,导致重复的业务处理。

增大配置超时时间

ribbon.ReadTimeout=10000

ribbon.ConnectTimeout=10000

eureka服务调用重试开关的配置属性:

默认开启。

重试机制:对于连接超时的异常,feign都会触发重试机制,对于读取超时,会根据请求类型判断,如果是GET异常,触发重试;其他异常,不会触发重试。

服务响应超时时间,默认5s,连接的超时时间为2s。

同一实例最大重试次数为1

负载均衡的其他实例的重试次数为2

对所有 *** 作请求都进行重试,默认false,建议不要开启。

一、简单说一下目前的系统

1.注册中心shop-eureka

2.网关shop-gateway

3.业务系统shop-business

4.用户服务shop-user-center

二、问题,现在我是在shop-bussiness系统中使用feign调用shop-user-center的接口

1.shop-user-center

2.shop-business中的feign接口:

3.shop-business中的feign接口使用

可以看出在图一中我设置sleep时间为7秒,最开始我自己不设置超时时间,在图上调用的时候肯定是报超时错误:java.util.concurrent.TimeoutException: null。

三、设置超时

1.在shop-gateway的application.properties中添加配置,设置的ReadTimeout是8秒,网上看的,说是全局设置:

ribbon.ReadTimeout=8000

ribbon.ConnectTimeout=6000

测试结果:java.util.concurrent.TimeoutException: null

2.在shop-gateway中application.properties添加配置:

ribbon.ReadTimeout=8000

ribbon.ConnectTimeout=6000

测试结果:java.util.concurrent.TimeoutException: null

3.在调用方shop-business中application.properties添加配置:

ribbon.ReadTimeout=8000

ribbon.ConnectTimeout=6000

测试结果:java.util.concurrent.TimeoutException: null

4.在调用方shop-business中application.properties添加配置:

shop-user-center.ribbon.ReadTimeout=8000

shop-user-center.ribbon.ConnectTimeout=6000

测试结果:成功。

四、总结

1.feign是客户端调用,shop-business是feignclient,所以在shop-business设置超时时间。

五、问题

1.如何设置全局超时时间?

表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒

leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。

leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。

是否开启自我保护模式,默认为true。

默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。

Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

Eureka server和client之间每隔30秒会进行一次心跳通信,告诉server,client还活着。由此引出两个名词:

Renews threshold :server期望在每分钟中收到的心跳次数

Renews (last min) :上一分钟内收到的心跳次数。

前文说到禁止注册server自己为client,不管server是否禁止,阈值(threshold)是1。client个数为n,阈值为1+2×n(此为一个server且禁止自注册的情况)

如果是多个server,且开启了自注册,那么就和client一样,是对于其他的server来说就是client,是要×2的

我开了两个server,自注册,相关数据如下

阈值:1+2×1

renews:

1)自注册 2 + 2×1

2)非自注册:2×1

Eurake有一个配置参数eureka.server.renewalPercentThreshold,定义了renews 和renews threshold的比值,默认值为0.85。当server在15分钟内,比值低于percent,即少了15%的微服务心跳,server会进入自我保护状态,Self-Preservation。在此状态下,server不会删除注册信息,这就有可能导致在调用微服务时,实际上服务并不存在。

这种保护状态实际上是考虑了client和server之间的心跳是因为网络问题,而非服务本身问题,不能简单的删除注册信息

stackoverflow上,有人给出的建议是:

1、在生产上可以开自注册,部署两个server

2、在本机器上测试的时候,可以把比值调低,比如0.49

3、或者简单粗暴把自我保护模式关闭


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/7891772.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存