Spring Microservices issue with @HystrixCommand

567 Views Asked by At

We are facing a problem with Hystrix Command in a Spring Boot / Cloud microservice. We have a Spring Component containing a method annotated with @RabbitListener. When a new message arrives, the method delegates the invocation to NotificationService::processNotification().

The NotificationService is a bean annotated with @Service. The method processNotification() can request third party applications. We want to wrap the invocation of third party applications using @HystrixCommand to provide fault tolerance, but due to some reasons the Hystrix Command annotated method is not working.

If we invoke a Controller and the Controller delegates the invocation to a Service method, which in turns have a Hystrix Command , everything works perfectly. The only problem with Hystrix Command arises when the microservices consume a messages and it seems to be Hystrix Command doesn’t trigger the fallback method.

Here is the non-working code:

@Component
public class MessageProcessor {

    @Autowired
    private NotificationService notificationService;

    @RabbitListener(queues = "abc.xyz-queue")
    public void onNewNotification(String payload) {
        this.notificationService.processNotification(payload);
    }

}

@Service
public class NotificationService {

    public void processNotification(String payload) {
        ...
        this.notifyThirdPartyApp(notificationDTO);
        ...
    }

    @HystrixCommand(fallbackMethod = "notifyThirdPartyAppFallback")
    public void notifyThirdPartyApp(NotificationDTO notificationDTO) {
        //Do stuff here that could fail
    }

    public void notifyThirdPartyAppFallback(NotificationDTO notificationDTO) {
        // Fallbacl impl goes here
    }

}

@SpringBootApplication
@EnableCaching
@EnableCircuitBreaker
@EnableDiscoveryClient
@EnableRabbit
public class NotificationApplication {

    public static void main(String[] args) {
        SpringApplication.run(NotificationApplication.class, args);
    }
}
1

There are 1 best solutions below

0
On

I'm not sure about your problem without looking at the code.

As another approach you can take: instead of describing this calls with annotations in your service, just extend HystrixCommand and implement api calling logic in it (read more):

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }
}