Blogue

Comment nous avons ramené les déploiements à zéro erreur 502

Chaque fois que nous déployions le backend de Mythex, quelques requêtes échouaient avec 502 Bad Gateway. Pas beaucoup, mais un 502 pendant un déploiement signifie qu'un clic de quelqu'un n'a rien fait, ou qu'une compilation suivie à l'écran s'est bloquée un instant. Nous avons retrouvé deux problèmes distincts : un chien de garde d'auto-réparation qui entrait en conflit avec nos déploiements, et un décalage entre le moment où un serveur cesse d'écouter et celui où le répartiteur de charge cesse de lui envoyer du trafic. Sur trois déploiements de production consécutifs après les corrections, le nombre est passé de 10 à 6, puis à 0.

Le contexte

Notre API et notre orchestrateur tournent comme des conteneurs sur un petit groupe de serveurs derrière un répartiteur de charge d'application AWS (ALB). Un déploiement met à jour un serveur à la fois : il vide les anciens conteneurs, en démarre de nouveaux, puis passe au suivant. Un chien de garde sur chaque serveur vérifie que les conteneurs sont en marche et redémarre ceux qui ne le sont pas — il existe pour qu'un processus planté à 3 h du matin revienne sans que personne ait à se réveiller.

Ces deux éléments se justifient chacun, mais ensemble, ils ne tenaient pas.

Problème 1 : le chien de garde entrait en course avec le déploiement

Le chien de garde s'exécutait une fois par minute et « réparait » à la suite d'un seul contrôle de santé raté. Or un déploiement vide volontairement les services pendant jusqu'à 150 secondes — pendant lesquelles un contrôle de santé est censé échouer. Le chien de garde se déclenchait donc pendant chaque déploiement.

La plupart du temps, il perdait la course sans conséquence. Une fois, il l'a gagnée : il a réécrit le fichier compose (la description des conteneurs qui doivent tourner) au milieu d'un déploiement, et a laissé un serveur sans aucun conteneur de passerelle — alors que la tâche de déploiement signalait un succès.

Les corrections :

  • Un seul verrou. Le déploiement prend maintenant le même verrou de fichier que le script d'amorçage du serveur, si bien que le chien de garde et un déploiement ne peuvent jamais tourner en même temps.
  • Quatre avertissements, pas un. Le chien de garde a besoin de quatre contrôles de santé consécutifs ratés avant d'agir. Un service en cours de vidage ne ressemble plus à un service mort.
  • Une seule définition. Le fichier compose a maintenant une seule source, publiée sur les serveurs, au lieu de copies susceptibles de diverger.
  • Vérifier, ne pas faire confiance. La tâche de déploiement ne réussit plus parce qu'une commande a renvoyé un résultat. Elle vérifie l'API, l'orchestrateur, la passerelle et le worker de publication de chaque serveur avant de pouvoir réussir.

Problème 2 : le serveur partait avant le trafic

Le second problème était plus discret. Lorsqu'un déploiement vide un serveur, celui-ci répond 503 sur son point de contrôle de santé pour que le répartiteur de charge le retire de la rotation. Le nôtre faisait cela pendant 5 secondes, puis s'arrêtait.

Or l'ALB ne vérifie la santé qu'à intervalles, et il lui faut plusieurs échecs consécutifs avant de cesser d'acheminer vers une cible — jusqu'à environ 60 secondes en tout. Pendant environ 55 secondes, le répartiteur continuait donc à envoyer de vraies requêtes à un serveur qui avait déjà cessé d'écouter. Ce sont nos 502.

La correction a consisté à faire concorder les deux échéanciers :

  • Le groupe cible vérifie maintenant toutes les 5 secondes et marque une cible comme non fonctionnelle après 2 échecs — environ 10 secondes pour le constater.
  • Le vidage continue de servir du vrai trafic pendant 15 secondes après le début de l'échec des contrôles de santé, afin qu'il y ait toujours un chevauchement.
  • Ces réglages sont dans le script qui provisionne l'infrastructure, et non dans une console qu'une personne a cliquée une fois.

Faire tenir les chiffres entre eux

Des délais comme ceux-ci dépendent les uns des autres. Le vidage doit durer plus longtemps que le temps que met le répartiteur à s'en apercevoir ; le vidage plus l'arrêt doivent se terminer avant que le conteneur ne soit tué de force. Il est facile que quelqu'un modifie un seul chiffre six mois plus tard et réintroduise le bogue sans le savoir.

Nous avons donc écrit ces relations sous forme de tests : le vidage doit être plus long que l'intervalle de contrôle multiplié par le seuil d'échec ; le délai pour redevenir sain doit rester court ; et tout le vidage doit tenir dans le délai d'arrêt accordé au conteneur. Si l'on modifie un chiffre sans les autres, la CI échoue. Nous avons aussi soumis les tests eux-mêmes à des mutations : nous avons remplacé chaque chiffre par une mauvaise valeur et vérifié qu'un test le détecte.

Mesurer un déploiement est facile à faire de travers

Notre première mesure indiquait qu'un déploiement propre était cassé à environ 3 %. Ce n'était pas le cas. Nous comptions chaque réponse qui n'était pas un 200, et un 503 d'un point de contrôle de santé pendant un vidage n'est pas un échec — c'est le vidage qui fait son travail, en indiquant au répartiteur de ne pas choisir ce serveur tout en continuant à servir de vraies requêtes.

Ce que l'utilisateur ressent, c'est un 502 : la requête n'a atteint rien du tout. Ne compter que ceux-là a donné le vrai portrait — 10, puis 6, puis 0 sur trois déploiements de production.

Ce que nous en avons retenu

  • L'auto-réparation doit connaître les arrêts planifiés. Un chien de garde incapable de distinguer un déploiement d'un plantage finira par entrer en conflit avec le déploiement.
  • Le vidage est une poignée de main. Le serveur doit continuer à servir jusqu'à ce que le répartiteur ait prouvé qu'il a cessé d'envoyer du trafic, et ce délai se règle sur le répartiteur, non sur le serveur.
  • Encodez les invariants sous forme de tests. Les chiffres opérationnels dérivent. Les tests qui les relient entre eux ne dérivent pas.
  • Décidez ce que vous mesurez avant de mesurer. « Erreurs » était la mauvaise mesure ; « requêtes qui n'ont atteint rien » était la bonne.

Si vous publiez une application sur Mythex, rien de tout cela n'est visible pour vous — ce qui est le but. Voir aussi : comment votre application publiée reste en ligne pendant que vous la republiez.

Mythex · Pricing · Créez n'importe quoi avec l'IA · Modèles de sites web et d'applications · Mythex comparé · Glossaire de la création d'applications avec l'IA · Outils gratuits pour créer des applications avec l'IA · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)