user3105453
user3105453

Reputation: 1981

Hystrix/Feign to solely react on HTTP status 429

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

Answers (2)

user3105453
user3105453

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

Kevin Davis
Kevin Davis

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

Related Questions