Spring Boot Cloud + Ribbon + Feign + Hystrix + Zookeeper:重试和失败是怎么回事?

Posted

技术标签:

【中文标题】Spring Boot Cloud + Ribbon + Feign + Hystrix + Zookeeper:重试和失败是怎么回事?【英文标题】:Spring Boot Cloud + Ribbon + Feign + Hystrix + Zookeeper: what's going on retries and failures? 【发布时间】:2017-07-23 15:36:28 【问题描述】:

我正在尝试使用 Ribbon + Feign + Hystrixspring-boot (1.5.1) 创建一些服务/strong>(我的服务发现是 spring-boot-zookeeper)并且我不使用 Zuul。

我(天真)认为它应该以下列方式工作:

调用 Feign 方法(由 @FeignClient 注释) - 它将其转换为一些 HTTP 请求,由 Ribbon 以某种方式负载均衡,因此如果发送请求失败,它会尝试(根据 Ribbon 配置,即 myservice.ribbon.MaxAutoRetriesNextServer=2)重试下一个相同类型/名称的服务,最后如果所有重试都失败 - 它调用 Hystrix 后备方法。

所以我的 Feign 界面

@FeignClient(value = "myservice", fallbackFactory = HystrixMyServiceFallbackFactory.class)
@RibbonClient(name = "myservice")
public interface MyServiceClient 
    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    Response foo(Object data);

定义 Hystrix FallbackFactory 以返回一些默认响应

public class HystrixMyServiceFallbackFactory implements FallbackFactory<MyServiceClient > 

    @Override
    public MyServiceClient create(final Throwable throwable) 
        return new MyServiceClient () 

            @Override
            public Response foo(Object data) 
                return new Response(-1, "Failed");
            
        ;
    

在我的代码中,我有以下几行:

@Autowired
private MyServiceClient myServiceClient;

public Response doSomething() 
   return myServiceClient.foo(new Object());

当所有服务都启动时(我有 2 个 MyService),Ribbon 可以很好地使用 Round Robbin,但是当我关闭一个 MyService 实例时,Ribbon 继续使用 Round Robbin,所以每第二次尝试,我都会收到 Hystrix 的结果回退,而不是预期的成功(功能区应该在其他服务上重试,不是吗?),直到功能区服务器列表更新。

任何人都可以解释它是如何一起工作的吗?

【问题讨论】:

【参考方案1】:

这可能就是您要查找的内容:https://***.com/a/29171396/873590

如果您使用的是功能区,您可以设置类似于 以下(用“localapp”代替您的 serviceid):

localapp.ribbon.MaxAutoRetries=5
localapp.ribbon.MaxAutoRetriesNextServer=5
localapp.ribbon.OkToRetryOnAllOperations=true

【讨论】:

【参考方案2】:

您需要检查几件事。

首先,检查您的 maven/gradle 文件是否具有 spring-retry 依赖项。 Feign + Ribbon 重试需要 spring-retry 并且它现在是可选的依赖。因此,如果您的应用程序中没有spring-retry,则不支持重试。

如果应用spring-retry 后没有发生重试,则需要检查原始异常消息。为此,请删除回退并检查消息。 如果消息有myservice timed-out,则表示发生了hystrix超时异常。

Hystrix 超时默认为 1,000 毫秒,如果您有较大的读取/连接超时,有时重试 http 请求是不够的。如果是这样,请尝试如下调整 hystrix 超时。

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000

上面的属性会将你所有默认的 hystrix 超时更改为 10 秒,它通常足够大。您需要将此值设置为正确的值,以便有足够的时间进行重试。

您还可以更改特定断路器的 hystrix 超时。在 Feign 的情况下,每个方法都有自己的断路器,它的名称如下所示。

MyServiceClient#foo(Object)

因此您可以像下面这样更改断路器的超时时间。

hystrix:
  command:
    MyServiceClient#foo(Object):
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000

【讨论】:

谢谢,我找到了这个配置。但在我看来,这在微服务环境中可能会有点问题。如果我有 5 个“服务”并且其中 2 个很慢,它不会解决我的问题:或者我将禁用所有“服务”组件(通过 Hystrix),或者禁用 hystrix。经过一番思考,我决定以不同的方式解决它:改善健康指标,因此“不良服务”将被快速标记为不健康,并通过服务发现从列表中删除。我仍然有服务缓慢的“问题”,但也许我应该定义什么是缓慢的,并再次将其标记为“坏”服务。

以上是关于Spring Boot Cloud + Ribbon + Feign + Hystrix + Zookeeper:重试和失败是怎么回事?的主要内容,如果未能解决你的问题,请参考以下文章

2.Spring Cloud Alibaba实现负载均衡-Ribbon

Spring Boot,Spring Cloud,Spring Cloud Alibaba 版本选择说明以及整理归纳

spring cloud 与 spring boot 和 spring cloud alibab 版本号对应

Spring Cloud Spring Boot mybatis分布式微服务云架构使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程

Spring Cloud 对应 Spring Boot 版本

spring-boot 指标与 spring-cloud 指标