我们通过直接扩展HystrixCommand类来使用Hystrix功能。但是对于一些业务异常,Hystrix的后备方法正在被触发。
我不想为某些特定于业务的异常触发Hystrix回退。如何在没有基于注释的情况下实现它?
使用ignoreExceptions注释参数
@HystrixCommand(ignoreExceptions = { BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class })
见https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation
我看到你正在扩展HystrixCommand而不是使用注释,但这没关系,只需在命令中设置该属性,它应该具有相同的效果。
不幸的是,Hystrix Command是由Builder模式创建的,所以你必须做一些黑客攻击。 ignoreExceptions被添加到DefaultProperties.java,它在HystrixCommandBuilder中使用
如果将逻辑包装在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);
}
}
表示提供的参数或状态而不是执行失败的错误的异常。与HystrixCommand抛出的所有其他异常不同,这不会触发回退,不会计入故障指标,因此不会触发断路器。
注意:仅当用户输入错误(例如IllegalArgumentException)时才应该使用此选项,否则会违反容错和回退行为的目的。
两种方法可以做到这一点。
@HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
@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);
}