Skip to main content
Advertisement

2.12 Retry and Resilience (Retry / Resilience4j)

External API, DB, and message broker calls can fail due to transient errors. Use Retry and Circuit Breaker to absorb failures and limit blast radius.

Reference: Spring Boot 3.2.x, spring-retry or Resilience4j

1. Spring Retry (@Retryable)

implementation 'org.springframework.retry:spring-retry'
@SpringBootApplication
@EnableRetry
public class Application { ... }
@Service
public class PaymentClient {

@Retryable(
retryFor = { RestClientException.class },
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public PaymentResult callExternalApi(PaymentRequest req) {
return restTemplate.postForObject(...);
}

@Recover // called after all retries are exhausted
public PaymentResult recover(RestClientException e, PaymentRequest req) {
log.error("Payment API call failed, fallback", e);
return PaymentResult.failed("Temporary error");
}
}
  • retryFor: Only retry on these exceptions
  • maxAttempts: Maximum number of attempts
  • backoff: Wait time (delay ms, increasing by multiplier)
  • @Recover: Signature must match (Exception, method args...)

2. Resilience4j — Circuit Breaker

Use Resilience4j to block calls for a period on consecutive failures, protecting resources.

implementation 'io.github.resilience4j:resilience4j-spring-boot3'
resilience4j:
circuitbreaker:
instances:
paymentApi:
registerHealthIndicator: true
slidingWindowSize: 10
minimumNumberOfCalls: 5
failureRateThreshold: 50
waitDurationInOpenState: 10s
@Service
public class PaymentService {

private final CircuitBreaker circuitBreaker;
private final PaymentClient client;

public PaymentService(CircuitBreakerRegistry registry, PaymentClient client) {
this.circuitBreaker = registry.circuitBreaker("paymentApi");
this.client = client;
}

public PaymentResult pay(PaymentRequest req) {
return circuitBreaker.executeSupplier(() -> client.callExternalApi(req));
}
}
  • failureRateThreshold: Circuit opens (OPEN) when failure rate exceeds this value
  • waitDurationInOpenState: After this duration in OPEN state, transitions to HALF_OPEN to probe

3. Retry + Circuit Breaker

Resilience4j allows registering both Retry and CircuitBreaker together. A common pattern is to retry a few times with Retry first, then open the CircuitBreaker if the failure rate is still high.


tip

Limit retried exceptions with retryFor and do not retry business errors (4xx etc.). Adjust external dependency timeouts together with RestTemplate/WebClient settings.

Advertisement