0
0
SpringbootHow-ToBeginner · 4 min read

How to Use Resilience4j with Spring Boot for Fault Tolerance

To use Resilience4j in a Spring Boot application, add the resilience4j-spring-boot2 dependency, enable @EnableCircuitBreaker, and annotate your service methods with @CircuitBreaker, @Retry, or other resilience annotations. Configure resilience policies in application.yml to control behavior like failure thresholds and wait durations.
📐

Syntax

Resilience4j integrates with Spring Boot by using annotations on methods to apply resilience patterns like circuit breakers and retries. You configure these patterns in your application.yml or application.properties. The main annotations are:

  • @CircuitBreaker(name = "backendService"): Wraps a method with a circuit breaker named backendService.
  • @Retry(name = "backendService"): Retries the method call on failure.
  • @RateLimiter(name = "backendService"): Limits the rate of calls.

Each annotation refers to a configuration block by name.

java
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @CircuitBreaker(name = "backendService", fallbackMethod = "fallback")
    @Retry(name = "backendService")
    public String callExternalService() {
        // call to external service
        return "Success";
    }

    public String fallback(Exception e) {
        return "Fallback response";
    }
}
💻

Example

This example shows a Spring Boot service using Resilience4j's circuit breaker and retry to call a simulated external service. If the service fails, it retries and then falls back gracefully.

java
package com.example.demo;

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Service
class ExternalService {
    private int attempt = 0;

    @CircuitBreaker(name = "backendService", fallbackMethod = "fallback")
    @Retry(name = "backendService")
    public String unreliableCall() {
        attempt++;
        if (attempt < 3) {
            throw new RuntimeException("Service failure");
        }
        return "Service success on attempt " + attempt;
    }

    public String fallback(RuntimeException e) {
        return "Fallback response due to: " + e.getMessage();
    }
}

@RestController
class TestController {
    private final ExternalService service;

    public TestController(ExternalService service) {
        this.service = service;
    }

    @GetMapping("/test")
    public String test() {
        return service.unreliableCall();
    }
}
Output
Service success on attempt 3
⚠️

Common Pitfalls

Common mistakes when using Resilience4j with Spring Boot include:

  • Not enabling @EnableCircuitBreaker or missing the Spring Boot starter dependency, so annotations have no effect.
  • Incorrect fallback method signatures that do not match the original method's parameters plus an exception parameter.
  • Misnaming the resilience4j configuration keys in application.yml, causing default settings to apply unexpectedly.
  • Using blocking calls inside reactive applications without adapting resilience4j properly.
java
/* Wrong fallback method signature example */
public String fallback() { // Missing Exception parameter
    return "Fallback";
}

/* Correct fallback method signature */
public String fallback(Exception e) {
    return "Fallback due to " + e.getMessage();
}
📊

Quick Reference

AnnotationPurposeKey Attribute
@CircuitBreakerWraps method with circuit breakername (config name), fallbackMethod
@RetryRetries method on failurename (config name)
@RateLimiterLimits call ratename (config name)
@BulkheadLimits concurrent callsname (config name)

Key Takeaways

Add the Resilience4j Spring Boot starter dependency to enable integration.
Use annotations like @CircuitBreaker and @Retry on service methods to add resilience.
Configure resilience policies in application.yml under the names used in annotations.
Fallback methods must match the original method signature plus an Exception parameter.
Test your resilience setup by simulating failures and verifying fallback behavior.