La spec MicroProfile Fault Tolerance 4.1 définit six politiques composables. Cette page expose le vocabulaire (Retry, Timeout, CircuitBreaker, Bulkhead, Fallback, Asynchronous), l’ordre canonique de composition imposé par §2.5, et la distinction conceptuelle entre les politiques de récupération et celles de protection.
Les six politiques
| Annotation | Famille | Rôle |
|---|---|---|
|
Récupération |
Ré-essais transparents en cas d’échec transitoire — délai, jitter, |
|
Protection |
Borne maximale du temps d’exécution d’une tentative. |
|
Protection |
Coupe les appels vers un service en panne — fenêtre glissante, transitions CLOSED/OPEN/HALF_OPEN. |
|
Protection |
Isole un point d’appel — sémaphore (sync) ou file bornée (async). |
|
Récupération |
Fournit un résultat alternatif quand toutes les autres politiques ont échoué. |
|
Exécution |
Délègue l’invocation à un virtual thread ; la méthode renvoie |
Distinction clé : récupération (@Retry, @Fallback) cherche à obtenir un résultat malgré l’échec ; protection (@Timeout, @CircuitBreaker, @Bulkhead) cherche à limiter le dommage subi par le système appelant.
Ordre canonique de composition
La spec MP FT 4.1 §2.5 impose un ordre de wrapping unique, de l’extérieur vers l’intérieur :
@Asynchronous se positionne au-dessus de cette chaîne quand il est présent : il bascule l’exécution sur un virtual thread, puis la chaîne @Fallback → … → méthode est invoquée dans ce thread.
Conséquence concrète : la composition est non-commutative. Un @Retry autour d’un @Timeout (ce que fait la chaîne) réessaie chaque tentative timée. À l’inverse, un @Timeout autour d’un @Retry (qu’on ne peut pas exprimer en MP FT) timerait la séquence entière de retries. La spec choisit la première forme — chaque tentative a son propre budget temps.
États du circuit breaker
@CircuitBreaker est un automate à trois états :
| État | Sémantique |
|---|---|
|
Les appels passent. La fenêtre |
|
Les appels sont rejetés immédiatement par un |
|
Une tentative de sonde est admise. Si |
Métaphore Heisenberg : l’état OPEN est l'effondrement du paquet d’ondes — l’observation a forcé le système dans un état discret, et il faut attendre delay avant que la superposition (sonde HALF_OPEN) ne redevienne possible.
@Fallback vs @CircuitBreaker
Confusion fréquente : les deux interviennent en cas d’échec, mais leur rôle est orthogonal.
| Aspect | @Fallback |
@CircuitBreaker |
|---|---|---|
Famille |
Récupération |
Protection |
Question posée |
« Que renvoyer si l’appel a échoué ? » |
« Faut-il encore essayer d’appeler ? » |
Effet sur l’appelant |
Voit un résultat (fallback) au lieu d’une exception |
Voit |
Effet sur le système distant |
Aucun — l’appel a déjà eu lieu |
Réduit la pression — les appels suivants sont court-circuités |
Les deux se combinent naturellement : @CircuitBreaker protège, @Fallback récupère le CircuitBreakerOpenException levé.
Sémantique de @Asynchronous
@Asynchronous exige que la méthode retourne CompletionStage<T> ou Future<T>. L’appel est délégué à un virtual thread. Pour CompletionStage :
-
L’intercepteur retourne immédiatement un
CompletableFuture<T>vide. -
Un virtual thread est créé (
Thread.ofVirtual().start(…)). -
La chaîne
@Fallback → @CircuitBreaker → @Bulkhead → @Timeout → @Retry → méthodes’exécute sur ce virtual thread. -
Quand le résultat est connu,
CompletableFuture.complete(value)est appelé.
Pour Future<T>, le contrat est plus restrictif : Future.cancel(true) interrompt le virtual thread (best-effort), Future.get(timeout) bloque le thread appelant jusqu’à timeout.
|
La méthode annotée |
Sémantique de @Bulkhead
@Bulkhead(value=N) borne le nombre d’invocations concurrentes :
-
Mode synchrone (sans
@Asynchronous) : unSemaphoreà N permis ; un appel au-delà lèveBulkheadExceptionimmédiatement. -
Mode asynchrone (avec
@Asynchronous) : unSemaphoreà N permis + une file dewaitingTaskQueuetâches en attente ; au-delà,BulkheadException.
Configuration via MicroProfile Config
La spec MP FT 4.1 §12 définit un schéma de clés fault-tolerance/… lu via MicroProfile Config — fourni par Ravel.
| Clé | Effet |
|---|---|
|
Valeur globale, prioritaire sur la valeur par défaut de l’annotation. |
|
Override au niveau classe. |
|
Override au niveau méthode — prioritaire absolu. |
|
Booléen. |
|
Booléen. |
Voir Référence pour la liste exhaustive et les variantes par paramètre.
Pour aller plus loin
-
Cas d’usage — chaînes typiques (
@Retry + @Timeout + @CircuitBreaker + @Fallback),FallbackHandler,@Asynchronous. -
Fonctionnement interne — pipeline d’invocation, moteurs purs, virtual threads,
StateRegistry. -
Référence — annotations, paramètres, clés MP Config.