0

Hystrix fallback with Zuul and Spring Boot

When we work with a Gateway Service like Zuul, probably we want to include a Circuit Breaker mechanism to avoid ugly errors in case of redirecting to a service which is unavailable or not responding in time. We can do that by connecting Hystrix with Zuul with a ZuulFallbackProvider bean. Let’s see how.

Introduction

What we want to accomplish here is a better error recovery strategy when a service behind a gateway is failing. In that scenario, the problem is that Zuul would return an Internal Server Error, which might end up crashing a web page or just giving a bad time to our REST API consumers.

We can avoid that using a Circuit Breaker pattern and, with Spring Boot, the best-integrated implementation is Spring Cloud Netflix Hystrix.

Getting it to work

I’ll use code from my GitHub project microservices-v8. It’s part of the complete microservices system example included in my book Microservices – The Practical Way. To give a short summary of the story here, we have two microservices fully integrated with Zuul for API routing, Eureka for Service Discovery and Ribbon to perform load balancing.

For our job here, we’ll focus on the gateway project. Regarding dependency configuration, we need to make sure of including the right libraries from Spring Cloud. I’m using Dalston.SR1 and spring-cloud-starter-zuul.

The routing configuration, as usual, is located in our application.yml:

If you know about Zuul route configuration this is not rocket science. I’m including it here so you can see the configuration for the /api/multiplications/** route. It’s being redirected to a service with id multiplication in Eureka.

The most interesting part is located inside the HystrixFallbackConfiguration class. There we need to inject a bean implementing ZuulFallbackProvider. Let’s check how it looks:

To make it work properly, it’s important to follow some basic instructions:

  • Regarding the fallbackResponse method:
    • Provide consistent results to getStatusCode, getRawStatusCode and getStatusText. To be honest, I don’t know why this interface looks so ugly, they’re just redundant methods. But you need to use them as they come.
    • Inside the getBody method, provide the fallback result for your request. In our case it’s a JSON response matching the format of a proper response to /multiplications/**. You need to wrap that as an InputStream according to the interface.
    • Set the proper headers for the response. In our case, that means including the right content type.
  • To set up the route that will handle this fallback you need to implement the getRoute method.
    • If you want to capture all routes, you can just specify ‘*’.
    • In case you work with Eureka it’s a little bit tricky. You don’t specify the route URL but the service id instead. In our example, multiplication.

That’s all we need. When this bean is injected and the service matching the route fails (most probably with a timeout), the request is getting handled by it, responding with the default ClientHttpResponse that we just configured. In our example, that implies showing an error to the user instead of providing them with multiplication factors. It’s not the best user experience ever, but it works better than an internal server error.

Testing it

You can test the provided code if you execute all the Spring Boot applications coming in that repository. It will set up Eureka, Ribbon and Zuul. If you want to start the UI as well, you only need to execute a jetty server with the provided configuration inside the ui folder.

The best option to see it working is to start two instances of the multiplication service (running in different ports). Leave the Service Discovery works and then just shut down one of them. In the next seconds, if you make a request to /api/multiplications/random (or use the main page in the UI), the fallback response will be returned. That’s an example of how ZuulFallbackProvider works with an open circuit.

If you have any questions about it don’t hesitate to write me a comment. In case you want to know more about Microservices with Spring Boot, explained from a very practical perspective, have a look at my book Microservices – The Practical Way. You’ll learn how to implement microservices with all these kind of related tools and patterns.

Related Posts

End-to-End Microservice Tests with Cucumber and Sp... If you work with Microservices, you surely faced the situation in which some of your system processes only make sense after the information flows thro...
How to deploy a Spring Boot WAR in Wildfly / JBoss This is a short guide on how to deploy a war packaged Spring Boot application in Wildfly. As you know Wildfly is the new name for JBoss AS since 8.0 v...

Leave a Reply