HystrixCommand的奇怪行为

问题描述

该项目使用SpringBoot(2.3.4)SpringCloud(Hoxton.SR8)
共有三类:BillController,BillService(接口)和BillServiceImpl(实现BillService),BillController调用在BillService中声明的函数getBillList

在BillServiceImpl中,有两种方法,一种是getBillList,另一种是simulateUnstableServicegetBillList调用simulateUnstableService,而在simulateUnstableService中只是很长一段时间睡眠(2000年)。

奇怪的是,如果我用getBillListHystrixCommand进行注释,那么它可以按我期望的那样工作。但是,如果我移动HystrixCommand来对simulateUnstableService进行注释,则不会中断,这意味着超时不会触发Circuit Breaker

@Service
public class BillServiceImpl implements BillService {

    @Override
    // have effact
    @HystrixCommand(
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
            }
    )
    public List<Bill> getBillList(long userId) {
        return simulateUnstableService(userId);
    }

// no effact
//    @HystrixCommand(
//            commandProperties = {
//                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
//            }
//    )
    public List<Bill> simulateUnstableService(long userId) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new ArrayList<>();
    }
}

还有更多,如果我只是将simulateUnstableService方法的内容复制到getBillList,并用HystrixCommand注释getBillList,则断路器也可以工作。
为什么?

解决方法

当电路中断时,调用后备方法。我们需要在hystrix命令中提及回退方法。后备方法的签名与hystrix注释的方法相同。

simulateUnstableService是您的后备方法吗?

@HystrixCommand(fallbackMethod='yourFallbackMethod'
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
            }
    )
    public List<Bill> getBillList(long userId) {
        return simulateUnstableService(userId);
    }

此外,优良作法是在application.properties文件中添加hystrix命令属性,而不是与注释一起提供。

,

很好的问题。

Hystrix 使用 AOP 来包装被调用的方法并提供电路制动功能。实际上有一个方面类 HystrixCommandAspect.java 定义了用于实现此目的的周围建议。

现在,如果您从类中调用方法,AOP 将无法正常工作。请参阅此答案以获得更清晰的信息 - Spring AOP not working for method call inside another method

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...