在我当前的项目中,我需要使用Hystrix进行请求回退处理(主要是请求超时回退)。我测试了一个简单的案例,它将@HystrixCommand注释放在一个spring rest controller方法之上,如下所示:
@RestController
public class xxxxxx {
@RequestMapping(value = "xxxxxxx")
@HystrixCommand(fallbackMethod="fallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "2000"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
public String xxxxxx(@RequestParam(value = "xxxx", required = true) String xxxx) {
....
return json.toString();
}
}
这非常有效。超时在2秒后触发,并进入我预定义的后退方法。现在问题出现了:控制器上有太多方法,项目中有很多控制器。通过方法复制和粘贴@HystrixCommand方法不是一个好主意,我需要通过spring aop实现它。 然后我写了如下内容:
@Aspect
@Configuration
public class TimeoutMonitor {
@Pointcut("execution(xxxxxxxx)")
public void excuteService() {}
@Around("excuteService()")
@HystrixCommand(fallbackMethod="fallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "2000"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
public Object monitor(ProceedingJoinPoint pjp){
try {
Object output = pjp.proceed();
return output;
}catch(Throwable e) {
return null;
}
}
@HystrixCommand
public String fallback(ProceedingJoinPoint pjp) {
JSONObject json = new JSONObject();
json.put("message", "request timeout");
return json.toString();
}
}
它不起作用......永远不会达到回退方法
在调试过程中,我确保逻辑流程通过excuteService() - > monitor() - >匹配方法的流程,并且它已经过了2秒,但是从未达到回退方法。我已经研究过这个问题,发现@HystrixCommand也是由AOP实现的。我想将一个aop放在另一个是导致这个问题的原因,但遗憾的是我无法想出解决它的方法。
如果有人能提供解决方案,我将不胜感激。也不允许使用aop实现的解决方案,但不允许在每种方法上复制和粘贴@HystrixCommand。
答案 0 :(得分:1)
由于对此问题仍无回应,我将在此处提出自己的临时解决方案。
首先,在spring aop中使用hystrix仍然不可行,所以唯一的努力就是减少对控制器端的影响。 Hystrix允许springboot application.properties文件中的默认超时设置如下:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=3000
通过这种方式,将每个方法放在上面的注释只减少到一行:
@HystrixCommand(fallbackMethod="fallback")
在这些方面仍然不够简洁:
需要为每个方法复制/粘贴此注释
需要在使用hystrix的每个地方复制/粘贴后备方法
虽然仍然不如我所说的那么简洁,但这是我目前所能想到的。一旦找到更好的解决方案,就会执行更新。