Search code examples
fallbackhystrix

Hystrix Calls the fallbackMethod even when backend API gets executed


I am trying to implement the Hystrix into our micro-services project. To keep the question simple and concise, I will describe the scenario below:

(a) A call to a backend service which is performing slow at times (e.g. Payment Service)

(b) I have annotated the method with @Hystrix (from where I am making the call to the payment service). Also, I have implemented the corresponding fallback method.

(c) Below is the code snippet for the same.

@HystrixCommand(fallbackMethod = "fallbackProcessPayment")
public String processPayment(User user) throws Exception
{  
    // Call the payment service (which is slow in nature) to process the payment for the user....
}

 public String fallbackProcessPayment(User user){       
    // This is the fallback method for processPayment....
    // Gracefully handle the processPayment 
}

In the config.properties file timeout is configured as 
hystrix.command.getUseCase1.execution.isolation.thread.timeoutInMilliseconds=2000

Current Behavior - As soon as call to the backend Payment service is made from processPayment(..) method, it takes longer (~ 4000 ms) than what I have set in the hystrix.command.getUseCase1.execution.isolation.thread.timeoutInMilliseconds (2000 ms) and hence Hystrix calls the fallbackProcessPayment (...) but what I also see is the fact that backend Payment service also gets executed albeit slowly. This is undesired behaviour as Payment is being processed in the background as I also notify the user (through the fallback method) that we are not able to process the payment (because the call was timed out as paymentService took 4 secs to respond whereas Hystrix expected the response in 2 secs (based on timeoutInMilliseconds configuration).

Is there are any configuration which I am missing to make it work properly ???

Any pointer into this would be of great help.

Thanks for your time


Solution

  • Well. This is the expected behaviour of hystrix. You have couple of options.
    1. Either increase the timeout
    2. In your fallback method check what is the reason for the method to fail. i.e. on which exception. (You can get to know this by adding a argument to your fallback method of type Throwable which will have the exception for which fallback method is triggered). If the failure is due to timeout then you can write a piece of code to check if the previous process completed or not before returning the response.

    But the second approach isn't feasible because, If you have set your threshold as 5 and if 5 requests fail due to timeout in succession then the 6th request will directly go to your fallback method. Where checking if previous process completed or not doesn't make sense.