Bon allez, moment de rigolade, enfin plutôt vous allez bien vous foutre de moi. On pourrait parler des sysadmins Unix qui ont fait rm -rf /
en tant que root involontairement sur un serveur de prod’, ben je vais vous parler des bugs que j’ai pu vivre (ou causer…) et qui m’ont causé le plus de sueurs froides…
Débloque les + belles offres tech en 10 mins
D’un autre côté on voulait permettre aux utilisateurs de lancer une action et de la mettre en file d’attente, bref on avait fait un système de lock qui devait en théorie permettre d’attendre qu’une tâche soit finie, avant de prendre l’autre. Sauf que… sous certaines conditions (les fameuses race-conditions) le système n’arrivait plus à locker et donc on se retrouver à tenter d’appeler la base de données en boucle. Bref on a planté le serveur de base de données comme ça, et la restauration de la base n’était pas une option car celle-ci n’avait pas été sauvegardée depuis trois semaines. Pour la petite histoire cette boîte prétendait conserver en sécurité les données des utilisateurs, mouahahahahahahaha.
On est reparti sur un système plus simple sans file d’attente des tâches et tout est rentré dans l’ordre.
Tout ceci aurait pu être détecté avec des tests de charge, sauf que bon, ceux-ci coûtaient trop cher aux yeux de la direction, donc ça n’a pas été fait. Moralité : toujours faire des tests de charge sur les applis.
Celui-là je l’ai vu deux fois. On avait ajouté un système d’indexation des fichiers à base Lucene, à une solution de partage de données en ligne. Et régulièrement on voyait que le serveur plantait, avec la charge CPU qui montait à 100% lors du monitoring.
Mon chef m’a demandé de regarder du côté de nos indexeurs, mais en cherchant un moment, je n’ai rien trouvé. Il ne voulait rien savoir, et me mettait la pression là-dessus. Finalement un jour où ça s’est reproduit et où il a daigné afficher les stack traces, on a vu un truc analogue à ceci :
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.get(HashMap.java:303)
at sun.font.SunLayoutEngine.getEngine(SunLayoutEngine.java:115)
at sun.font.GlyphLayout$EngineRecord.init(GlyphLayout.java:642)
at sun.font.GlyphLayout.nextEngineRecord(GlyphLayout.java:494)
at sun.font.GlyphLayout.layout(GlyphLayout.java:417)
at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:308)
at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:294)
at sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:208)
at sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:117)
at java.awt.font.TextLine.init(TextLine.java:264)
at java.awt.font.TextLine.(TextLine.java:110)
at java.awt.font.TextLine.fastCreateTextLine(TextLine.java:952)
at java.awt.font.TextLayout.fastInit(TextLayout.java:585)
at java.awt.font.TextLayout.(TextLayout.java:511)
at sun.java2d.SunGraphics2D.drawString(SunGraphics2D.java:2804)
Pour la petite histoire c’est un rapport de bug récurrent sur la JVM qui est toujours rejeté par Oracle, car en fait en environnement multithread il faut toujours utiliser des structures thread-safe, si celles-ci doivent être partagées entre threads…
Dans la même veine on m’a demandé un jour de faire un test de charge sur une appli Web JEE contenant le même bug dans un filtre HTTP. Très rapidement le load average est monté à 40 sur une machine à 4 CPU, et les gens de la prod’ m’ont demandé d’arrêter le test en urgence de peur de faire fumer les serveurs…
UPDATE
en base, et une utilisation de Spring qui faisait appel partout à des getBean
. Oui vous voyez c’est magnifique, et le sentiment que j’ai eu vis-à-vis du gars qui m’a refilé son bébé était ceci :
Il y avait notamment une table en base qui contenait des taux de facturation, et celle-ci était remplie à chaque fois qu’on ouvrait un document de facturation. Sauf que… si les taux changeaient, les anciens taux n’étaient pas purgés. Ce qui fait qu’à la fin, quand on chargeait ce document, Hibernate choisissait les taux… au hasard parmi ceux qui étaient dispo. Et voilà comment les factures changeaient de montant à chaque ouverture.
Allez, pour rigoler un peu, sachez que la sécurité sur l’appli était inexistante, et qu’avec un simple petit JavaScript ou appel CURL on pouvait vider complètement la base de données de production… Autant dire que oui, c’était de l’authentique code de m*rde…
Bon allez, ça vous dit d’exposer vos propres bugs ? Allez, déchaînez-vous sur les commentaires. 🙂
Débloque les + belles offres tech en 10 mins
Cet article vous a plu ? Vous aimerez sûrement aussi :
Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.
Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.
Elles sont passées où les femmes dans la tech ? Entre le manque de représentation…
Dans cette vidéo, on interview Nicolas Grekas, contributeur clé de Symfony, pour discuter de sa…
Comment trouver son job dans la tech ? Marie a la réponse ! Grâce à…
Adobe, l'empire créatif, et pas des moindres ! Belle ascension de la part de ces…
Est-ce plus simple de créer des morceaux avec les outils de Musique Assistée par Ordinateur…