提问者:小点点

Spring Boot Cloud Ribbon飞行Hystrix动物园管理员:重试和失败发生了什么?


我正在尝试使用Ribbon FeignHystrix(我的服务发现是spring-boot-zoogger)使用spring-boot(1.5.1)创建一些服务,并且我不使用Zuul。

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

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

所以我的模拟界面

@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可以很好地运行,但是当我关闭一个MyService实例时,Ribbon会继续使用圆形Robbin,所以每第二次尝试,我都会收到Hystrix Fallback的结果,而不是预期的成功(功能区应该在其他服务上重试,不是吗?),直到功能区服务器列表更新。

有人能解释一下这一切是如何运作的吗?


共2个答案

匿名用户

这可能就是你要找的:https://stackoverflow.com/a/29171396/873590

如果您使用功能区,您可以设置类似于以下的属性(将您的serviceid替换为localapp):

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

匿名用户

有几件事你需要检查。

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

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

hystrix超时默认为1,000ms,如果您有大的读取/连接超时,有时重试超文本传输协议请求是不够的。如果是这样,请尝试调整hystrix超时,如下所示。

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

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

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

MyServiceClient#foo(Object)

因此,您可以更改断路器的超时时间,如下所示。

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