Repérer les applications qui plantent juste après la publication
Le 25 septembre, trois publications ont été marquées comme réussies alors que l'API de l'application plantait quelques secondes après chaque démarrage. Comme elles avaient « réussi », aucune restauration n'a été lancée; une vérification en arrière-plan les a déclarées en échec quelques minutes plus tard, et tout le site a renvoyé une erreur 404. Le contrôle de santé comptait les plantages dans la liste d'événements de la plateforme d'hébergement, qui ne conserve que les cinq derniers événements par machine. Une boucle de plantages remplit donc toujours la liste, et le compte ne monte jamais. Il compare maintenant l'heure du plus récent plantage, et une publication qui boucle sur les plantages échoue et restaure la version précédente.
Ce qu'attend une publication
Lorsque vous publiez une application avec un backend sur Mythex, la nouvelle version est déployée sur des machines de notre plateforme d'hébergement, et un contrôle de santé décide si la publication est en ligne ou a échoué. En cas d'échec, une restauration remet la version précédente en place.
Le point délicat est que « démarré » n'est pas la même chose que « en service ». La plateforme signale une machine comme démarrée dès qu'elle est debout. Une application qui plante une seconde après son démarrage est relancée aussitôt, et un instant plus tard elle est de nouveau lue comme démarrée. Le contrôle de santé s'était donc enrichi de plusieurs couches au fil du temps :
- Regarder deux fois. Après qu'une machine est lue comme démarrée, attendre brièvement puis regarder de nouveau. Un plantage au démarrage fait souvent échouer le second regard.
- Surveiller les boucles de plantage. Si la plateforme signale qu'une machine n'a cessé de planter et qu'elle a abandonné les redémarrages, échouer.
- Compter les plantages depuis le début de la publication. Deux regards « démarré » peuvent encadrer un redémarrage. Donc si un plantage s'est produit depuis le début de cette publication, regarder une troisième fois; s'il y a plus de plantages qu'au regard précédent, l'application ne reste pas debout.
C'est la troisième vérification qui a échoué ici.
Pourquoi le compte restait plat
L'information sur les plantages provient de la liste d'événements de chaque machine : démarrages, arrêts, redémarrages. La plateforme ne conserve que les cinq derniers événements par machine.
Imaginez une application qui plante 2,5 secondes après chaque démarrage, comme l'une d'elles. Chaque cycle ajoute un plantage et un démarrage. Après quelques cycles, la liste est pleine. Ensuite, chaque nouvel événement en pousse un ancien dehors. La liste glisse vers l'avant, mais garde toujours à peu près le même mélange : quelques plantages, quelques démarrages.
Ainsi, « combien de plantages depuis le début de la publication » renvoyait le même nombre à chaque regard. Le deuxième regard voyait, disons, deux plantages. Le troisième en voyait aussi deux : des plantages différents, mais le même compte. La vérification concluait que les plantages avaient cessé, et validait la publication.
Cela s'est produit trois fois le 25 septembre, sur deux applications. À chaque fois :
- la publication était marquée comme en ligne,
- aucune restauration n'a été lancée, puisque rien n'avait échoué,
- notre réconciliateur, une tâche en arrière-plan qui vérifie les déploiements après coup, a fait échouer le déploiement quelques minutes plus tard,
- et tout le site a renvoyé une erreur 404.
Une publication qui échoue à temps peut être récupérée : la restauration remet la version précédente. Une publication qui échoue quelques minutes en retard, après avoir été déclarée réussie, a déjà sauté sa restauration.
Comment nous l'avons trouvé
Nous l'avons reproduit localement : nous avons pris une API qui fonctionnait, l'avons laissée se mettre en veille, puis l'avons republiée avec une modification qui plantait au démarrage. Le contrôle de santé l'a marquée comme en ligne.
Cela correspondait à la production : dans chacune des trois publications, l'application mourait quelques secondes après chaque démarrage, pourtant le compte de plantages comparé par le contrôle ne montait jamais entre deux regards.
La correction : comparer le plantage le plus récent, pas le compte
Au lieu de compter les plantages, la vérification regarde maintenant l'heure du plantage le plus récent depuis le début de la publication.
Si le deuxième regard montre un plantage survenu depuis le début de la publication, la vérification attend et regarde une troisième fois. Si le plantage le plus récent du troisième regard est postérieur à celui du deuxième, la machine a planté de nouveau entre-temps. Elle ne reste pas debout, et la publication échoue avec un message indiquant que la machine a planté à répétition depuis la publication et redémarre encore.
Cela fonctionne quelle que soit la longueur de la liste d'événements. Une fenêtre glissante de cinq événements peut cacher combien de plantages il y a eu, mais elle ne peut pas cacher qu'un nouveau vient de se produire : l'événement le plus récent est toujours celui qui est conservé.
Avec ce changement, la reproduction locale se comporte correctement : la publication échoue, et l'image précédente est restaurée. Il existe aussi un test qui simule le comportement de la plateforme (à chaque regard, un plantage et un démarrage s'ajoutent, et la liste est ramenée à cinq) et vérifie que le verdict est un échec, et non un succès.
Ce que nous en retenons
- Connaissez la forme des données que vous comptez. Un compte sur une liste plafonnée ne veut plus rien dire une fois la liste pleine. Le plafond n'était pas caché; nous n'avions simplement pas conçu la vérification en tenant compte de lui.
- Préférez « est-ce qu'il s'est passé quelque chose de nouveau? » à « combien en est-il arrivé? » L'horodatage le plus récent survit à la troncature. Un total, non.
- Un échec tardif est pire qu'un échec précoce. La même version défectueuse est inoffensive si la publication échoue et revient en arrière; elle met un site hors service si elle est d'abord déclarée réussie.
- Reproduisez avec les conditions réelles. Le bogue exigeait une machine qui avait déjà planté assez de fois pour remplir sa liste d'événements. Un seul plantage rapide dans un test ne l'aurait pas montré.
Cette correction s'accompagne d'une autre, du même jour, qui a fait en sorte que la restauration remette l'ancienne version en place au lieu de la supprimer : une republication ratée ne supprime jamais un backend fonctionnel. Si votre propre application ne se publie pas parce qu'elle plante au démarrage, la documentation sur le dépannage de la publication et notre guide sur le débogage d'une application créée par IA sont de bons points de départ.