Blogue

Une republication ratée ne supprime jamais un backend fonctionnel

Le 25 septembre, une republication ratée a supprimé le backend d'une application qui fonctionnait sans problème depuis environ deux heures et demie. Le code qui annule une publication échouée a retiré chaque application serveur touchée par la publication, y compris celles qui servaient déjà avant qu'elle commence. Désormais, seules les applications créées par une publication peuvent être supprimées; une application déjà existante est remise sur la version exacte qu'elle exécutait auparavant. Deux correctifs de suivi, le même jour, ont fait en sorte que cette annulation s'exécute aussi lorsque l'outil de déploiement de la plateforme d'hébergement échoue, et qu'une application en bonne santé ne soit pas déclarée en échec simplement parce qu'elle était en veille.

Comment un backend est publié

Lorsque votre application Mythex a un backend, c'est-à-dire une API ou un serveur plutôt que de simples fichiers statiques, la publication le construit à partir d'un Dockerfile (une recette qui empaquette l'application dans une image) et déploie cette image sur des machines de notre plateforme d'hébergement. Ensuite, un contrôle de santé attend que la nouvelle version démarre réellement et reste en marche avant que la publication soit marquée comme active.

Si quelque chose échoue en cours de route, une restauration s'exécute pour tout annuler. Bien réussir cette restauration compte plus que presque n'importe quoi d'autre dans la publication, parce qu'elle s'exécute précisément lorsque quelque chose tourne déjà mal.

Problème 1 : la restauration supprimait ce qu'elle aurait dû rétablir

La restauration tenait une liste des applications serveur sur lesquelles une publication avait été déployée, et en cas d'échec, les détruisait toutes. C'est correct pour une première publication : l'application vient d'être créée, rien ne dépend d'elle, et la supprimer remet les choses dans leur état initial.

C'est exactement faux pour une republication. L'application existait déjà et servait de vrais visiteurs. Le 25 septembre, l'API d'une application qui fonctionnait depuis environ deux heures et demie a été supprimée par une republication ratée.

Une deuxième défaillance se cachait dans le même code. Lorsque la suppression n'aboutissait pas, la nouvelle image défectueuse restait sur les machines, alors que nous indiquions au propriétaire que son site actuel était toujours en ligne. Au moment où le contrôle de santé peut échouer, la nouvelle image a déjà été déployée sur toutes les machines. Ne rien faire n'est pas la même chose que défaire.

La correction : supprimer seulement ce que vous avez créé, restaurer le reste

Chaque publication enregistre désormais, pour chaque application serveur qu'elle touche :

  • si cette publication l'a créée, et
  • si ce n'est pas le cas, quelle image elle exécutait juste avant.

En cas d'échec, chaque application reçoit l'un de trois traitements :

  1. Créée par cette publication : on la supprime, comme avant.
  2. Existait déjà, image précédente connue : on redéploie l'image précédente avec la même configuration. Aucune construction; seule l'image revient en arrière.
  3. Existait déjà, image précédente inconnue : on n'y touche pas. Une application existante n'est jamais supprimée, même lorsqu'on ne peut pas la restaurer.

Ces règles forment une petite fonction pure dotée de ses propres tests : la décision ne peut pas revenir à « tout supprimer » sans qu'un test échoue.

Problème 2 : l'outil de déploiement pouvait échouer avant que nous ayons noté comment défaire

Peu après cette correction, nous avons trouvé une lacune. L'outil de déploiement de la plateforme exécute ses propres vérifications de fumée : si les nouvelles machines plantent, il se termine avec une erreur. Mais il le fait après que la nouvelle image est déjà sur les machines.

Notre code n'inscrivait une application dans la liste de restauration qu'une fois l'outil revenu avec succès. Lorsque l'outil lui-même faisait échouer le déploiement, l'application n'était pas encore sur la liste, donc rien n'était restauré. Dans notre environnement de préproduction, une republication défectueuse a laissé l'image défectueuse en service.

La correction : enregistrer l'annulation avant de commencer

L'application est maintenant inscrite pour la restauration, avec l'indication de sa création et de l'image qu'elle exécutait, dès qu'elle est préparée et avant qu'on y déploie quoi que ce soit. Quoi qu'il échoue ensuite, la restauration sait ce qu'il faut remettre en place. Nous l'avons vérifié localement : une republication défectueuse a échoué dans les vérifications de fumée de l'outil de déploiement, et la version précédente a continué de répondre.

Problème 3 : une application en veille était déclarée « jamais démarrée »

Les applications publiées sur Mythex se mettent en veille lorsqu'elles sont inactives, pour économiser vos crédits. Une republication laisse une machine en veille arrêtée, donc le contrôle de santé doit la réveiller. Il demandait à la plateforme de démarrer la machine une seule fois, et ignorait la réponse.

Le 25 septembre, cette unique demande de démarrage n'a mené nulle part. Une API en bonne santé est restée arrêtée pendant les cinq minutes complètes du contrôle de santé, puis a été déclarée en échec avec « 1 machine jamais démarrée (dernier état : arrêtée) ».

La plateforme refuse parfois un démarrage. Pendant nos tests, elle a renvoyé un conflit « lease currently held » sans que nous le provoquions, et elle refuse les démarrages pendant qu'une machine est mise à jour.

La correction : continuer à demander, et frapper à la porte

Le contrôle de santé fait maintenant ceci :

  • il redemande de démarrer une machine arrêtée toutes les 20 secondes pendant l'attente,
  • il journalise la réponse de la plateforme lorsqu'elle refuse, et
  • il envoie une requête ordinaire à l'application, comme le ferait un visiteur : le mandataire de la plateforme réveille une machine en veille lorsqu'une requête arrive.

Nous avons reproduit le problème sur la vraie plateforme avec une application jetable dont le premier démarrage était refusé. Avant la correction, la publication échouait après 91 secondes. Après, elle était publiée en 20 secondes. Une application qui plante vraiment au démarrage échoue toujours, comme il se doit.

Ce que nous en retenons

  • La restauration doit distinguer le nouveau de l'existant. « Annuler » quelque chose que vous avez créé signifie le supprimer. « Annuler » quelque chose qui existait déjà signifie le restaurer. Traiter les deux de la même façon, c'est ainsi qu'un mécanisme de sécurité supprime une application fonctionnelle.
  • Notez comment défaire avant d'agir. Si l'annulation n'est enregistrée qu'après la réussite d'une étape, une étape qui échoue à mi-chemin ne laisse rien pour annuler.
  • Ne jamais ignorer la réponse à une demande dont vous dépendez. Un « non » ignoré a transformé une application en bonne santé en publication échouée.

Une correction liée, du même jour : les applications qui plantent juste après la publication. Pour ce qui se passe lorsqu'une publication échoue de votre côté, consultez le dépannage de la publication dans la documentation.

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 简体中文 繁體中文(香港) 繁體中文(台灣)