Article
Outils de résilience et discipline de lucidité
Timeouts, retries, circuit breaker, idempotence, outbox, DLQ : les outils de résilience, et la discipline de lucidité qui en fait une architecture.
Face à une frontière qui peut tarder, perdre ou dupliquer, on n'improvise pas : une poignée de mécanismes éprouvés suffit. Mais ils ne font pas une architecture à eux seuls — ils servent une discipline, celle de rendre explicites les compromis distribués au lieu de les masquer.
Devant un appel qui échoue par intermittence, la tentation est d'ajouter un retry en deux lignes, sans borne. Le jour où la dépendance ralentit pour de bon, chaque client réessaie en boucle et le correctif transforme une panne passagère en surcharge — le système encaissant l'assaut de ses propres clients. La boîte à outils existe pour ne pas réinventer ces gestes dans l'urgence. Elle tient en trois familles.
La boîte à outils
Borner l'attente : timeout, circuit breaker, bulkhead
Le timeout limite le temps qu'on accorde à l'autre ; il n'annule pas l'opération distante, il signale surtout une perte de certitude locale. Le circuit breaker coupe court quand une dépendance est manifestement défaillante, le temps qu'elle se rétablisse, plutôt que de s'acharner ; il rouvre par prudence, en laissant d'abord passer une seule requête de test — l'état « semi-ouvert » — avant de refermer le circuit. Le bulkhead cloisonne les ressources — pools, files, workers séparés — pour qu'une saturation locale ne se propage pas à tout le système.
Réessayer sans nuire : retry, backoff, jitter
Le retry traite les erreurs transitoires, à trois conditions : un nombre de tentatives borné, un backoff idéalement exponentiel, et un peu de jitter pour désynchroniser les clients. Surtout, distinguer l'erreur rejouable de l'erreur définitive : réessayer une requête malformée ne la rendra pas valide, cela ajoutera du bruit.
Garantir la convergence : idempotence, outbox, inbox
C'est ici la clé de voûte : l'idempotence. Dès qu'un message peut être redélivré, retrié, reçu en double ou confirmé de façon incertaine — c'est-à-dire toujours, à travers une frontière — il faut pouvoir le rejouer sans changer deux fois l'état métier. Une clé d'idempotence, un identifiant métier stable, un journal des traitements appliqués : sans eux, chaque retry est un risque. (L'idempotence neutralise les doublons et les rejeux, pas le désordre : remettre des messages dans l'ordre est un autre problème — clé de partition, numéro de séquence.) L'outbox garde cohérents, dans une même transaction locale, le changement d'état et l'événement qui l'annonce — plus de message perdu dans l'écart entre la base et le bus, à charge pour le relais qui draine l'outbox de faire son travail ; mais l'événement est alors publié au moins une fois — une coupure passagère peut le republier en double —, ce qui rend l'inbox obligatoire en miroir, côté récepteur : elle mémorise les messages déjà traités pour dédupliquer, et simuler un exactement une fois. La file de rebut (DLQ) isole ce qui n'a pu être traité — utile à condition d'être relevée : une DLQ qu'on ne traite jamais n'est pas un filet, c'est un cimetière où l'échec passe pour un succès.
Aucun de ces outils n'est sophistiqué. Pris isolément, chacun répond à un risque précis ; assemblés autour de l'idempotence, ils transforment une frontière incertaine en frontière gérée. Reste à ne pas les confondre avec une fin en soi : un retry n'est pas une décision métier, et une DLQ ne réconcilie rien. Ils bornent le désordre ; ils ne disent pas ce qui, du désordre, est acceptable.
Une discipline de lucidité
Ces mécanismes servent quelque chose de plus large. Vu de bout en bout, CAP n'est pas un théorème de bases distribuées mais une méthode : à chaque frontière, se demander ce qui se passe quand le lien faiblit. D'étiquette à coller sur un système, il devient un cadre de décision pour l'incident ; de souci réservé aux bases réparties, une attention due à toute frontière, jusque dans un monolithe.
Cette discipline tient en quelques partis pris :
- rendre visibles les compromis plutôt que les masquer — un mode dégradé qu'on n'a pas écrit se découvre en production ;
- n'exiger la cohérence forte que là où elle protège un invariant réellement critique, jamais par confort ;
- accepter ailleurs des mécanismes de convergence contrôlée — cohérence éventuelle assumée, réconciliation, compensation ;
- documenter les comportements de dégradation et de reprise, pour qu'ils soient choisis et non subis.
En pratique, elle se ramène à une grille de questions, à poser devant chaque frontière avant de la franchir : quelle est la source de vérité ? Quel invariant doit être vrai immédiatement ? Que se passe-t-il si le composant distant ne répond pas ? Peut-on différer l'opération sans casser le métier ? Que voit l'utilisateur pendant le délai ? Comment détecte-t-on un désalignement, comment le réconcilie-t-on, faut-il compenser et par quel geste ? L'opération est-elle idempotente ? Dispose-t-on d'une trace corrélée pour comprendre, après coup, ce qui s'est passé ? Aucune n'est savante ; c'est de ne pas se les poser qu'on paie le prix.
On retrouve ici la discipline jumelle du sens des dépendances. Là, on orientait les flèches du couplage pour protéger l'autonomie des modules ; ici, on sécurise la physique de ces liens une fois tracés. Orienter d'abord, blinder ensuite : c'est ainsi qu'on bâtit des jointures à la fois souples et durables, là où se joue — bien plus que dans les composants eux-mêmes — ce qu'on pourra encore changer demain.
Une dernière remarque, qui vaut au-delà des architectures réparties. CAP n'est pas réservé aux systèmes étalés sur plusieurs continents : dès que deux composants communiquent, fût-ce dans le même processus, l'état, le temps et l'échec deviennent imparfaitement observables. La lucidité demande seulement de ne pas faire comme si la frontière n'existait pas.
Laisser un commentaire
Vous devez être connecté pour pouvoir laisser un commentaire.