如何说 Hystrix 不会为 Hystrix 命令中的某些异常触发回退
Posted
技术标签:
【中文标题】如何说 Hystrix 不会为 Hystrix 命令中的某些异常触发回退【英文标题】:How to say Hystrix not to trigger fallback for some of the exceptions in Hystrix command 【发布时间】:2017-10-30 00:47:45 【问题描述】:我们通过直接扩展 HystrixCommand 类来使用 Hystrix 功能。但是对于一些业务异常,正在触发Hystrix的fallback方法。
我不想针对某些业务特定异常触发 Hystrix 回退。我如何在没有基于注释的情况下实现它?
【问题讨论】:
【参考方案1】:使用 ignoreExceptions 注释参数
@HystrixCommand(ignoreExceptions = BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class )
见https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation
我看到您正在扩展 HystrixCommand 而不是使用注释,但这没关系,只需在命令中设置该属性,它应该具有相同的效果。
不幸的是,Hystrix 命令是由 Builder 模式创建的,因此您必须进行一些黑客操作。在 HystrixCommandBuilder 中使用的 DefaultProperties.java 中添加了 ignoreExceptions
【讨论】:
据我了解。在 HystrixCommandBuilder 的 ignoreexceptions 方法中,他只是在复制异常列表。但是根据方法注释,我了解到这些被忽略的异常可以包含在 Hystrixbadrequestexception 中。但是你能告诉我如何做到这一点,并以更好的方式使用代码 sn-p “只需在命令中设置该属性”-HystrixCommand
中没有此类属性【参考方案2】:
如果您将逻辑包装在 try/catch 中并在 HystrixBadRequestException 中重新抛出任何异常,则它不会触发回退。
@Override
protected Object run() throws Exception
try
return //call goes here
catch (Throwable e)
//We wrap any exceptions in a HystrixBadRequestException because this way any other errors will not
//trip the short circuit
throw new HystrixBadRequestException("Exception thrown hystrix call", e);
来自文档: http://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/exception/HystrixBadRequestException.html
表示带有提供的参数或状态的错误而不是执行失败的异常。 与 HystrixCommand 抛出的所有其他异常不同,这不会触发回退,不计入故障指标,因此不会触发断路器。
注意:这仅应在错误是由于用户输入(例如 IllegalArgumentException)引起时使用,否则它会破坏容错和回退行为的目的。
【讨论】:
【参考方案3】:有两种方法可以做到这一点。
使用 HystrixCommand 注解并指定异常类型。
@HystrixCommand(ignoreExceptions = HttpStatusCodeException.class, JsonMappingException.class )
使用“HystrixBadRequestException”并自定义代码以忽略少数异常情况或状态代码。此实现将检查您的后端 API 合同预期的异常的特定错误代码,并且不会调用 hystrix 回退。抛出“HystrixBadRequestException”不会算作 hystrix 故障。
@HystrixCommand(commandKey = "MyHystrixCommand", fallbackMethod = "myHystrixFallback", threadPoolKey = "ThreadPoolKey")
public ResponseEntity<String> getServiceCallResponse(String serviceUrl, HttpEntity<?> entity)
ResponseEntity<String> resp = null;
try
resp = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, String.class)
.getBody();
catch(Exception e)
handleExceptionForHystrix("getServiceCallResponse", e);
return resp;
private void handleExceptionForHystrix(String function, Exception e)
if (e instanceof HttpStatusCodeException)
HttpStatus httpStatusCode = ((HttpStatusCodeException)e).getStatusCode();
if(httpStatusCode.equals(HttpStatus.BAD_REQUEST) || httpStatusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR))
throw new HystrixBadRequestException("Hystrix Bad Request Exception Occurred" + httpStatusCode, e);
throw new RuntimeException(function, e);
throw new RuntimeException(function, e);
public ResponseEntity<String> myHystrixFallback(String serviceUrl, HttpEntity<?> entity, Throwable hystrixCommandExp)
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
【讨论】:
以上是关于如何说 Hystrix 不会为 Hystrix 命令中的某些异常触发回退的主要内容,如果未能解决你的问题,请参考以下文章