Service under microservices architecture must be designed with failure in mind. It means writing code to deal with fault scenarios in such a way that the application remains responsive and always returns something to the user. With the use of the circuit breaker pattern1 and the retry pattern2 for solving self-correcting and cascading failure, in some cases, when the the service request fails after retry, we need an alternative response to the request (It can be in some case to return data from cache instead of read database).
Fallback pattern definition
Fallback provides an alternative solution during a service request failure. When the circuit breaker trips and the circuit is open, a fallback logic can be started instead. The fallback logic typically does little or no processing, and return value. Fallback logic must have little chance of failing, because it is running as a result of a failure to begin with.
Each service that’s wrapped by a circuit breaker can implements a fallback using one of the following three approaches:
- Custom fallback: In some cases a service’s client library provides a fallback method we can invoke, or in other cases we can use locally available data on an API server (eg, a cookie or local JVM cache) to generate a fallback response
- Fail silent: In this case the fallback method simply returns a null value, which is useful if the data provided by the service being invoked is optional for the response that will be sent back to the requesting client
- Fail fast: Used in cases where the data is required or there’s no good fallback and results in a client getting a 5xx response. This can negatively affect the device UX, which is not ideal, but it keeps API servers healthy and allows the system to recover quickly when the failing service becomes available again.
Integration with other patterns
Using Fallback pattern with Circuit breaker pattern and Retry pattern, we will have this workflow:
1. “Circuit breaker pattern”, This content ↩
2. “Retry pattern”, This content ↩