Reputation: 1981
I'm using Feign
from the spring-cloud-starter-feign
to send requests to a defined backend. I would like to use Hystrix
as a circuit-breaker but for only one type of use-case: If the backend responds with a HTTP 429: Too many requests
code, my Feign client should wait exactly one hour until it contacts the real backend again. Until then, a fallback method should be executed.
How would I have to configure my Spring Boot (1.5.10) application in order to accomplish that? I see many configuration possibilities but only few examples which are - in my opinion - unfortunately not resolved around use-cases.
Upvotes: 0
Views: 3397
Reputation: 1981
I could solve it with the following adjustments:
Properties in application.yml
:
hystrix.command.commandKey:
execution.isolation.thread.timeoutInMilliseconds: 10_000
metrics.rollingStats.timeInMilliseconds: 10_000
circuitBreaker:
errorThresholdPercentage: 1
requestVolumeThreshold: 1
sleepWindowInMilliseconds: 3_600_000
Code in the respective Java class:
@HystrixCommand(fallbackMethod = "fallbackMethod", commandKey = COMMAND_KEY)
public void doCall(String parameter) {
try {
feignClient.doCall(parameter);
} catch (FeignException e) {
if (e.status() == 429) {
throw new TooManyRequestsException(e.getMessage());
}
}
}
Upvotes: 0
Reputation: 1293
This can be achieved by defining an ErrorDecoder
and taking manual control of the Hystrix
Circuit Breaker. You can inspect the response codes from the exceptions and provide your own fallback. In addition, if you wish to retry the request, wrap and throw your exception in a RetryException
.
To meet your Retry requirement, also register a Retryer
bean with the appropriate configuration. Keep in mind that using a Retryer
will tie up a thread for the duration. The default implementation of Retryer
does use an exponential backoff policy as well.
Here is an example ErrorDecoder taken from the OpenFeign
documentation:
public class StashErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
if (response.status() >= 400 && response.status() <= 499) {
return new StashClientException(
response.status(),
response.reason()
);
}
if (response.status() >= 500 && response.status() <= 599) {
return new StashServerException(
response.status(),
response.reason()
);
}
return errorStatus(methodKey, response);
}
}
In your case, you would react to 419
as desired.
You can forcibly open the Circuit Breaker setting this property at runtime
hystrix.command.HystrixCommandKey.circuitBreaker.forceOpen
ConfigurationManager.getConfigInstance()
.setProperty(
"hystrix.command.HystrixCommandKey.circuitBreaker.forceOpen", true);
Replace HystrixCommandKey
with your own command. You will need to restore this circuit breaker back to closed after the desired time.
Upvotes: 1