strange behavior of HystrixCommand

230 views Asked by At

The project uses SpringBoot(2.3.4) and SpringCloud(Hoxton.SR8).
There are three classes: BillController, BillService(interface) and BillServiceImpl (implements BillService), BillController calls function getBillList declared in BillService.

In BillServiceImpl, there are two method, one is getBillList, the other is simulateUnstableService, getBillList calls simulateUnstableService, and in simulateUnstableService just a long sleep(2000).

The strange thing is that if I annoate getBillList with HystrixCommand, then it works as I expect. But if I move HystrixCommand to annoate simulateUnstableService, then there is no break which means timeout does not trigger 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<>();
    }
}

And more, if I just copy simulateUnstableService method content to getBillList, and annoate getBillList with HystrixCommand, the breaker also works.
Why?

2

There are 2 answers

0
Mukul Bansal On BEST ANSWER

Excellent question.

Hystrix uses AOP to wrap the method being called and deliver the Circuit Braking functionality. There is actually an aspect class HystrixCommandAspect.java which defines the around advice used to achieve this.

Now, AOPs don't exactly work if you call a method from within a class. See this answer for more clarity- Spring AOP not working for method call inside another method

0
Prakriti Shaurya On

When the circuit breaks the fallback method is called. We need to mention fallback method inside the hystrix command. The fallback method has the same signature as the method being annotated by hystrix.

Is simulateUnstableService your fallback method?

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

Also, it is good practice to add the hystrix command properties inside the application.properties file instead of providing along with the annotation.