我正在尝试使用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的结果,而不是预期的成功(功能区应该在其他服务上重试,不是吗?),直到功能区服务器列表更新。
有人能解释一下这一切是如何运作的吗?
这可能就是你要找的: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