首页 > 解决方案 > HystrixCommand 的奇怪行为

问题描述

该项目使用SpringBoot(2.3.4)SpringCloud(Hoxton.SR8).
共有三个类:BillController、BillService(interface) 和BillServiceImpl(实现BillService),BillController 调用BillServicegetBillList中声明的函数。

在 BillServiceImpl 中,有两种方法,一种是getBillList,另一种是simulateUnstableServicegetBillList调用simulateUnstableService,以及在simulateUnstableService一个长睡眠中(2000 年)。

奇怪的是,如果我getBillList用进行注释HystrixCommand,那么它会按我的预期工作。但是,如果我移动HystrixCommand到 annoate 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 进行注释,那么断路器也可以工作。
为什么?

标签: spring-cloudhystrixcircuit-breaker

解决方案


很好的问题。

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

现在,如果您从类中调用方法,AOP 将无法正常工作。请参阅此答案以获得更清晰的信息-Spring AOP 不适用于另一个方法中的方法调用


推荐阅读