Hystrix fallback with Zuul and Spring Boot
Table of Contents
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.
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 Learn Microservices with Spring Boot. 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.
You can find all the source code on GitHub: Microservices V8
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
The routing configuration, as usual, is located in our
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
- Provide consistent results to
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
InputStreamaccording to the interface.
- Set the proper headers for the response. In our case, that means including the right content type.
- Provide consistent results to
- To set up the route that will handle this fallback you need to implement the
- 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,
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.
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
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 Learn Microservices with Spring Boot. You’ll learn how to implement microservices with all these kind of related tools and patterns.