Qu'est-ce que Resilience4j et pourquoi l'utiliser ?
Resilience4j est une bibliothèque légère pour Java, conçue pour améliorer la résilience des microservices et des systèmes distribués. Elle fournit un ensemble de composants prêts à l'emploi qui aident à protéger votre application contre les défaillances en cascade, les surcharges et les réponses lentes des services externes (bases de données, API, files de messages, etc.).
L'objectif principal de la bibliothèque est d'implémenter des modèles de résilience tels que Circuit Breaker (désactivation automatique d'un service défaillant), Rate Limiter (limitation du taux de requêtes), Retry (tentatives répétées), Bulkhead (isolation des ressources), Time Limiter (limitation du temps d'exécution) et Cache (mise en cache des résultats).
La bibliothèque s'intègre parfaitement dans l'écosystème Spring Boot, mais peut également être utilisée dans toute autre application Java. Resilience4j est considéré comme le remplacement moderne de l'ancienne bibliothèque Hystrix de Netflix.
Installation (Maven/Gradle)
Resilience4j est une bibliothèque Java, elle s'installe donc via les systèmes de build Maven ou Gradle. Contrairement à Python, la commande pip install n'est pas utilisée ici.
Maven (pom.xml)
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-all</artifactId>
<version>2.2.0</version>
</dependency>
<!-- Pour Spring Boot en complément -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.2.0</version>
</dependency>
Gradle (build.gradle)
implementation 'io.github.resilience4j:resilience4j-all:2.2.0'
implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
Démarrage rapide avec un exemple de code
Créons un exemple simple d'utilisation du Circuit Breaker. Supposons que nous ayons une méthode qui appelle une API externe. Nous voulons que si l'API répond avec une erreur 5 fois de suite, les appels suivants renvoient immédiatement une valeur de repli (fallback), sans solliciter le service défaillant.
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import java.time.Duration;
import java.util.function.Supplier;
public class QuickStartExample {
public static void main(String[] args) {
// 1. Création de la configuration du Circuit Breaker
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // Seuil d'erreur en pourcentage
.waitDurationInOpenState(Duration.ofMillis(1000)) // Durée en état ouvert
.slidingWindowSize(5) // Taille de la fenêtre glissante pour le comptage des erreurs
.build();
// 2. Création du registre et du Circuit Breaker
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("myService");
// 3. Encapsulation de l'appel risqué
Supplier<String> decoratedSupplier = CircuitBreaker
.decorateSupplier(circuitBreaker, QuickStartExample::riskyOperation);
// 4. Exécution multiple
for (int i = 0; i < 10; i++) {
try {
String result = decoratedSupplier.get();
System.out.println("Succès : " + result);
} catch (Exception e) {
System.out.println("Erreur : " + e.getMessage());
}
}
}
// Simulation d'un service externe peu fiable
public static String riskyOperation() {
if (Math.random() > 0.3) {
throw new RuntimeException("Service temporairement indisponible !");
}
return "Données