Disjoncter pour sauver le système
Par Christian Sperandio
- 4 minutes de lecture - 768 motsDans un précédent article, je parlais de l’utilisation d’un timeout sur les appels externes. Reprenons le dernier schéma :
Le composant A abandonne l’appel vers B au bout de 80ms. Il doit maintenant répondre à son client. La meilleure réponse devrait être la vérité, c’est à dire retourner que le système rencontre un ralentissement. Au client de gérer cette erreur.
Dans certains cas, il est acceptable (voire préférable) de retourner un résultat qui peut être :
- une valeur par défaut
- la dernière valeur calculée
Le besoin de retourner une valeur est plus souvent métier que technique. Prenons comme exemple un site de commerce de figurines de pingouin. Ce site a parmi ses services, un donnant la description d’une figurine, un donnant la disponibilité et le dernier pour le prix.
Organisation des 3 services
Si le service donnant la disponibilité ne peut répondre, il serait frustrant d’avoir une erreur et bloquer tout processus d’achat. Retourner que par défaut la figurine est disponible est envisageable, quitte ensuite à gérer une indisponibilité de manière commerciale.
Une figurine est par défaut disponible
L’utilisation de la dernière valeur « reçue » peut concerner le prix d’une figurine. Ce prix bougeant peu, il est raisonnable de le conserver dans un cache. Cela permettra de le récupérer si le service des prix ne répond pas.
Récupération du dernier prix de la figurine connu
Encore une fois, cette solution technique est acceptable par le métier car les prix bougent peu sur ce genre d’articles et surtout, le métier accepte de prendre le risque si le prix affiché n’est pas le bon (à la hausse comme à la baisse).
C’est un point important : beaucoup de solutions techniques peuvent avoir un impact business. Alors autant en référer aux personnes concernées.
Complexité liée à l’ajout d’un cache
Il est important de ne pas sous estimer l’ajout d’un cache au sein d’un système. Tout cache vient avec ses règles de rétention et d’éviction de la donnée. De plus, le cache ayant de grandes probabilités d’être distribué, nous ajoutons un système externe, qui peut devenir à son tour un PoF (point of failure).
Revenons à notre exemple initial:
Nous sommes à un point où nous gérons les difficultés du composant B à répondre aux sollicitations du composant A.
Nous pouvons dire que A est préservé des aléas de B. Mais le composant B, qui a des difficultés, continue de recevoir des requêtes et il peut même en recevoir encore plus par secondes vu que le composant A fonctionne avec un blocage limité.
C’est à ce moment qu’il faut savoir « péter les plombs » 🙂
Circuit breaker
Si votre logement répond aux normes électriques actuelles, vous devez avoir un tableau appelé disjoncteur différentiel.
C’est un ensemble d’interrupteurs qui coupent le courant sur une partie de votre circuit électrique dès qu’il y a une anomalie (sur-tension ou fuite à la terre par exemple). Ce dispositif a pour objectif de préserver vos appareils.
Dans le monde logicielle, nous avons une implémentation: le circuit breaker (c’est juste la traduction de disjoncteur en anglais). Le principe est de faire passer les appels de A vers B via un circuit breaker. Tant qu’il n’y a pas de problème, le circuit breaker laisser passer les appels, on dit qu’il est en position « fermé ».
Le circuit laisse passer les appels
Si des erreurs se produisent, le circuit breaker va commencer à calculer un taux d’erreurs sur une période à partir du nombre d’appels et du nombre d’erreurs. A partir d’un certain seuil, le circuit breaker « disjoncte » (il passe en position « ouvert ») et les appels vers B ne sont plus réaliser pendant une certaine durée.
Le circuit breaker “saute”
Au bout d’une certain temps, le circuit breaker passe en position « semi fermé » : en d’autres termes, il tente de faire passer des appels vers le composant B. Si ces appels passent alors le circuit breaker redevient fermé sinon il reste ouvert.
Ce mécanisme permet ainsi d’arrêter de solliciter le composant B en difficulté et réduit le blocage du composant A.
En reliant tout ceci avec du monitoring et des alertes, nous avons un moyen d’éviter la paralysie globale du système avec des composants qui pédalent. Dès qu’un circuit breaker passe en position « ouvert », une alerte devrait être levée afin de permettre à l’exploitation de chercher sa cause (réseau, manque de ressources systèmes).
Côté implémentations de circuit breaker, dans le monde Java nous avons Resilient4J
et l’historique Hystrix
.
Dans le monde Go, il y a quelques implémentations comme gobreaker
Note: Cet article a également été publié sur LinkedIN