Blog

Comment nous sommes arrivés à zéro erreur 502 lors des déploiements

À chaque déploiement du backend de Mythex, quelques requêtes échouaient avec 502 Bad Gateway. Pas beaucoup — mais une 502 pendant un déploiement signifie qu'un clic d'utilisateur n'a rien fait, ou qu'une construction suivie à l'écran s'est figée un instant. Nous avons remonté la cause à deux problèmes distincts : un watchdog d'auto-réparation qui luttait contre 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 compte est passé de 10 à 6, puis à 0.

La configuration

Notre API et notre orchestrateur tournent sous forme de 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, démarre les nouveaux, et passe au suivant. Un watchdog sur chaque serveur vérifie que les conteneurs sont actifs et redémarre ceux qui ne le sont pas — il existe pour qu'un processus planté à 3 h du matin revienne sans que personne ne soit réveillé.

Chacun de ces éléments est raisonnable seul. Ensemble, ils ne l'étaient pas.

Problème 1 : le watchdog entrait en concurrence avec le déploiement

Le watchdog s'exécutait une fois par minute et « réparait » sur un seul contrôle de santé échoué. Or un déploiement vide volontairement les services pendant jusqu'à 150 secondes — pendant lesquelles un contrôle de santé doit justement échouer. Le watchdog 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 désormais le même verrou de fichier que le script d'initialisation du serveur, si bien que le watchdog et un déploiement ne peuvent jamais tourner en même temps.
  • Quatre avertissements, pas un. Le watchdog a besoin de quatre contrôles consécutifs échoués avant d'agir. Un service en cours de vidage ne ressemble plus à un service mort.
  • Une seule définition. Le fichier compose a désormais une seule source, publiée sur les serveurs, au lieu de copies qui pouvaient diverger.
  • Vérifier, ne pas faire confiance. La tâche de déploiement ne réussit plus parce qu'une commande a renvoyé un code de sortie. 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. Quand un déploiement vide un serveur, celui-ci commence à répondre 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.

Mais l'ALB ne vérifiait la santé que périodiquement, et il fallait plusieurs échecs consécutifs avant qu'il cesse d'envoyer du trafic à une cible — jusqu'à environ 60 secondes de bout en bout. Pendant environ 55 secondes, le répartiteur de charge continuait donc d'envoyer de vraies requêtes à un serveur qui avait déjà cessé d'écouter. C'étaient nos 502.

La correction a consisté à faire coïncider les deux calendriers :

  • Le groupe cible vérifie désormais toutes les 5 secondes et marque une cible comme défaillante après 2 échecs — environ 10 secondes pour s'en apercevoir.
  • Le vidage continue de servir du trafic réel pendant 15 secondes après le début des échecs de contrôle, pour qu'il y ait toujours un chevauchement.
  • Ces paramètres vivent dans le script qui provisionne l'infrastructure, et non dans une console sur laquelle quelqu'un a cliqué 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 dont le répartiteur a besoin pour remarquer la panne ; 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 chiffre dans six mois et réintroduise discrètement le bogue.

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 avant de redevenir sain doit rester court ; l'ensemble du 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étectait.

Mesurer un déploiement est facile à mal faire

Notre première mesure indiquait qu'un déploiement propre était cassé à environ 3 %. Ce n'était pas vrai. Nous comptions chaque réponse qui n'était pas un 200, et un 503 du point de contrôle 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 pendant qu'il continue à servir de vraies requêtes.

Ce que ressent l'utilisateur, c'est une 502 : la requête n'a atteint rien. Ne compter que celles-ci donnait le vrai tableau — 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 watchdog incapable de distinguer un déploiement d'un plantage finira par se battre contre 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 calendrier se règle sur le répartiteur, pas sur le serveur.
  • Encodez les invariants dans des tests. Les chiffres opérationnels dérivent. Les tests qui les relient entre eux, non.
  • Décidez de ce que vous mesurez avant de mesurer. « Erreurs » était la mauvaise métrique ; « 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 — et c'est précisément le but. À lire aussi : comment votre application publiée reste en ligne pendant que vous la republiez.

Mythex · Pricing · Créez tout avec l'IA · Modèles de sites 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 (Canada) ગુજરાતી हिन्दी 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 简体中文 繁體中文(香港) 繁體中文(台灣)