
Il s'agit d'un deuxième article d'une série "Citymobil - un manuel pour améliorer la disponibilité au milieu de la croissance des entreprises pour les startups." Vous pouvez lire la première partie
ici . Continuons à parler de la façon dont nous avons réussi à améliorer la disponibilité des services Citymobil. Dans le premier article, nous avons appris à compter les déplacements perdus. Ok, nous les comptons. Et maintenant? Maintenant que nous sommes équipés d'un outil compréhensible pour mesurer les déplacements perdus, nous pouvons passer à la partie la plus intéressante - comment réduire les pertes? Sans ralentir notre croissance actuelle! Puisqu'il nous a semblé que la part du lion des problèmes techniques provoquant la perte de voyages avait quelque chose à voir avec le backend, nous avons décidé de tourner d'abord notre attention vers le processus de développement du backend. Sautant devant moi, je vais dire que nous avions raison - le backend est devenu le site principal de la bataille pour les voyages perdus.
1. Comment fonctionne le processus de développement
Les problèmes sont généralement causés par le déploiement de code et d'autres actions manuelles. Les services qui ne sont jamais modifiés et touchés à la main sont parfois également des dysfonctionnements, cependant, c'est une exception qui ne fait que confirmer la règle.
D'après mon expérience, l'exception la plus intéressante et inhabituelle était la suivante. En 2006, lorsque je travaillais dans l'un des petits services de messagerie Web, il y avait une passerelle qui contrôlait tout le trafic et s'assurait que les adresses IP n'étaient pas sur les listes noires. Le service fonctionnait sur FreeBSD et cela fonctionnait bien. Mais un jour, il a juste cessé de fonctionner. Devinez pourquoi? Le disque de cette machine est tombé en panne (des blocs défectueux se sont formés depuis un certain temps et l'inévitable s'est produit) et cela s'est produit trois ans avant la panne du service. Tout était en vie avec le disque défaillant. Et puis FreeBSD, pour des raisons connues de lui-même, a soudainement décidé d'adresser le disque défaillant et s'est arrêté en conséquence.
Quand j'étais enfant, 10-12 ans, je suis allé faire une randonnée dans les bois avec mon père et j'ai entendu une phrase de lui que je n'ai jamais oublié: "tout ce que vous devez faire pour garder le feu de joie est de ne pas le toucher". Je crois que la plupart d'entre nous se souviennent d'une situation où nous avons alimenté du bois au feu déjà brûlant et qu'il s'éteignait sans raison.
L'essentiel est que les problèmes sont créés par les actions manuelles des humains; par exemple, lorsque vous alimentez du bois dans le feu de joie déjà bien brûlé, coupant ainsi l'oxygène et tuant le feu ou en déployant le code avec des bogues en production. Par conséquent, pour comprendre les causes des problèmes de services, nous devons comprendre le fonctionnement du processus de déploiement et de développement.
Dans Citymobil, le processus était entièrement axé sur le développement rapide et organisé de la manière suivante:
- 20-30 sorties par jour.
- Les développeurs effectuent le déploiement par eux-mêmes.
- Test rapide en environnement de test par le développeur.
- Tests automatisés / unitaires minimaux, révision minimale.
Les développeurs ont travaillé dans des conditions difficiles sans support QA, avec un énorme flux de tâches très importantes de la part de l'équipe produit et des expériences; ils ont travaillé aussi intensément et uniformément que possible, ils ont résolu les tâches difficiles d'une manière simple, ils ont veillé à ce que le code ne se transforme pas en spaghetti, ils ont compris les problématiques commerciales, ont traité les changements de manière responsable et ont rapidement annulé ce qui ne fonctionnait pas. Il n'y a rien de nouveau ici. Il y avait une situation similaire au service Mail.Ru il y a 8 ans lorsque j'ai commencé à travailler là-bas. Nous avons démarré
Mail.ru Cloud rapidement et facilement, sans prélude. Nous changerions notre processus en cours de route pour obtenir une meilleure disponibilité.
Je parie que vous l'avez remarqué vous-même: quand il n'y a pas de blocage, quand c'est juste vous et la production, quand vous portez un lourd fardeau de responsabilité - vous faites des merveilles. J'ai vécu une expérience comme ça. Il y a longtemps, j'étais à peu près le seul développeur du service de messagerie Web Newmail.Ru (il a été acquis il y a quelque temps, puis retiré); J'ai effectué le déploiement par moi-même et effectué des tests de production sur moi-même via
if (!strcmp(username, "danikin")) { … some code… }
. Donc, je connaissais cette situation.
Je ne serais pas surpris de découvrir qu'une telle approche «rapide et sale» a été utilisée par de nombreuses startups à la fois réussies et non, mais toutes animées par une seule passion: le désir de croissance rapide de l'entreprise et de parts de marché.
Pourquoi Citymobil avait-il un tel processus? Il y avait très peu de développeurs pour commencer. Ils travaillaient pour l'entreprise depuis un certain temps et connaissaient très bien le code et les affaires. Le processus a fonctionné idéalement dans ces conditions.
2. Pourquoi la menace de disponibilité est-elle apparue?
Croissance des investissements dans le développement de produits provoquée par nos plans de produits pour devenir plus agressifs et nous avons commencé à embaucher plus de développeurs. Le nombre de déploiements par jour augmentait, mais naturellement leur qualité a diminué puisque les nouveaux gars ont dû plonger dans le système et les affaires dans des conditions de terrain. L'augmentation du nombre de développeurs a entraîné non seulement une baisse linéaire, mais également une baisse quadratique de la disponibilité (le nombre de déploiements augmentait linéairement et la qualité d'un déploiement moyen diminuait linéairement, donc "linéaire" * "linéaire" = "quadratique").
De toute évidence, nous ne pouvions pas continuer comme ça. Le processus n'a tout simplement pas été conçu pour ces nouvelles conditions. Cependant, nous avons dû le modifier sans compromis sur le temps de mise sur le marché; c'est-à-dire, en conservant 20 à 30 versions par jour (étant donné que leur nombre augmenterait à mesure que l'équipe s'agrandit). Nous grandissions rapidement, nous avons mené de nombreuses expériences, évalué rapidement les résultats et mené de nouvelles expériences. Nous avons rapidement testé des hypothèses sur les produits et les affaires, en avons tiré des enseignements et avons fait de nouvelles hypothèses que nous avons testées à nouveau rapidement et ainsi de suite. Nous ne ralentirons en aucun cas. De plus, nous voulions accélérer et embaucher des développeurs plus rapidement. Ainsi, nos actions visant à la croissance des entreprises ont créé une menace de disponibilité, mais nous n'avions absolument aucune intention de modifier ces actions.
3. Ok, la tâche est définie, le processus est clair. Et ensuite?
Avoir une expérience de travail au service de messagerie Mail.Ru et Mail.Ru Cloud où la disponibilité à un moment donné avait été prioritaire, où les déploiements avaient lieu une fois par semaine, où tout était couvert par des tests automatisés et unitaires et le le code a été revu au moins une fois, mais parfois même trois fois, j'ai été confronté à une situation totalement différente.
On pourrait penser que tout était assez simple: nous pourrions reproduire le processus de messagerie / cloud Mail.Ru chez Citymobil, augmentant ainsi la disponibilité du service. Cependant, comme on dit - le diable est dans les détails:
- les déploiements dans Mail.Ru e-mail / cloud sont effectués une fois par semaine, pas 30 fois par jour; chez Citymobil, nous ne voulions pas sacrifier la quantité de rejets;
- dans Mail.Ru email / cloud, le code est couvert par le test automatique / unitaire et nous n'avions ni le temps ni les ressources pour cela chez Citymobil; nous avons lancé tous nos efforts de développement backend dans des hypothèses et des tests d'amélioration de produit.
Cela dit, nous étions limités en termes de développeurs de backend, même s'ils étaient embauchés rapidement (un merci spécial aux recruteurs de Citymobil - les meilleurs recruteurs du monde! Je pense qu'il y aura un article séparé sur notre processus de recrutement) , il était donc impossible de résoudre les problèmes de test et d'examen sans ralentir.
4. Lorsque vous ne savez pas quoi faire, apprenez des erreurs
Alors, qu'est-ce que c'est si magique que nous avons fait chez Citymobil? Nous avons décidé d'apprendre des erreurs. La méthode d'amélioration des services tirée des erreurs est aussi ancienne que le temps. Si le système fonctionne bien, c'est bien. Si le système ne fonctionne pas bien, il est également bon car nous pouvons apprendre des erreurs. Plus facile à dire que ... En fait, cela peut aussi se faire facilement. La clé est de se fixer un objectif.
Comment avons-nous appris? Tout d'abord, nous avons commencé à écrire religieusement les informations sur chaque panne, grande ou petite. Pour être honnête, je n'avais vraiment pas envie de faire ça au début car j'espérais un miracle et je pensais que les pannes s'arrêteraient tout seules. De toute évidence, rien ne s'arrêtait. La nouvelle réalité a impitoyablement exigé quelques changements.
Nous avons commencé à enregistrer toutes les pannes dans un tableau Google Documents. Pour chaque panne, il y avait les informations succinctes suivantes:
- date, heure, durée;
- la cause profonde;
- ce qui a été fait pour résoudre le problème;
- impact sur les entreprises (nombre de voyages perdus, autres résultats);
- plats à emporter.
Pour chaque grosse panne, nous créerions un gros fichier distinct avec une description détaillée minute par minute du moment où la panne a commencé jusqu'à la fin: ce que nous avons fait, quelles décisions ont été prises. Cela s'appelle généralement un post-mortem. Nous ajouterions les liens vers ces autopsies dans le tableau général.
Il y avait une raison pour créer un tel fichier: arriver à des conclusions qui viseraient à diminuer le nombre de voyages perdus. Il était très important d'être très précis sur ce qu'est "la cause profonde" et ce que sont "les plats à emporter". Le sens de ces mots est clair; cependant, tout le monde peut les comprendre différemment.
5. Exemple d'une panne que nous avons apprise
La cause profonde est un problème qui doit être résolu afin d'éviter de tels accidents à l'avenir. Et les conclusions - les moyens d'éliminer la cause profonde ou de réduire la probabilité de sa résurgence.
La cause profonde est toujours plus profonde qu'elle ne semble l'être. Les plats à emporter sont toujours plus compliqués qu'ils ne le semblent. Vous ne devriez jamais être satisfait par la cause racine prétendument trouvée et ne jamais être satisfait des déclarations alléguées, afin de ne pas vous détendre et de vous arrêter à ce qui semble être juste. Cette insatisfaction crée une étincelle pour une analyse plus approfondie.
Permettez-moi de vous donner un exemple concret: nous avons déployé du code, tout est tombé en panne, nous l'avons restauré, tout fonctionnait à nouveau. Quelle est la cause profonde du problème? Vous diriez:
déploiement. Si vous n'aviez pas déployé de code, il n'y aurait pas eu d'accident. Alors, quel est le point à retenir: plus de déploiements? Ce n'est pas un très bon plat à emporter. Donc, très probablement, ce n'était pas la cause première, nous devons creuser plus profondément.
Déploiement avec un bug. C'est la cause profonde? D'accord. Comment le réparons-nous? Vous diriez en testant. Quel genre de test? Par exemple - test de régression complet de toutes les fonctionnalités. C'est un bon plat à emporter, rappelons-le. Mais nous devons augmenter la disponibilité ici et maintenant avant de mettre en œuvre le test de régression complet. Nous devons creuser encore plus profondément.
Déploiement avec un bogue provoqué par une impression de débogage dans la table de base de données; nous avons surchargé la base de données et elle est tombée sous la charge. Ça sonne mieux. Maintenant, il est devenu clair que même un test de régression complet ne nous sauvera pas de ce problème. Puisqu'il n'y aura pas de charge de travail sur la base de données de test similaire à la charge de travail de production.
Quelle est la cause profonde de ce problème, si nous creusons encore plus profondément? Nous avons dû parler à des ingénieurs pour le savoir. Il s'est avéré que l'ingénieur s'était habitué à ce que la base de données puisse gérer n'importe quelle charge de travail. Cependant, en raison de la croissance rapide de la charge de travail, la base de données ne pouvait pas à ce moment-là gérer ce qu'elle avait géré la veille. Très peu d'entre nous ont eu la chance de travailler pour les projets avec un taux de croissance de 50% par mois. Pour moi, par exemple, c'était le premier projet comme ça. Après avoir plongé dans un projet comme celui-là, vous commencez à comprendre de nouvelles réalités. Vous ne saurez jamais que c'est là-bas jusqu'à ce que vous le rencontriez.
L'ingénieur a trouvé la bonne façon de résoudre le problème: l'impression de débogage doit être effectuée dans un fichier qui doit être écrit via un script cron dans la base de données dans un thread. Au cas où il y aurait trop d'impression de débogage, la base de données ne descendra pas; les données de débogage apparaîtront simplement tôt ou tard. Cet ingénieur a visiblement appris de son erreur et ne recommencera pas. Mais d'autres ingénieurs devraient également le savoir. Comment? Ils doivent être informés. Comment les faire écouter? En leur racontant toute l'histoire du début à la fin, en exposant les conséquences et en proposant une manière correcte de le faire; et aussi, en écoutant et en répondant à leurs questions.
6. Que pouvons-nous apprendre d'autre de cette erreur ou des "choses à faire et à ne pas faire".
Ok, continuons d'analyser cette panne. L'entreprise se développe rapidement, de nouveaux ingénieurs arrivent. Comment vont-ils apprendre de cette erreur? Faut-il en parler à chaque nouvel ingénieur? De toute évidence, il y aura de plus en plus d'erreurs - comment faire en sorte que tout le monde apprenne d'eux? La réponse est presque claire: créez un fichier à faire et à ne pas faire. Nous allons écrire tous les plats à emporter dans ce fichier. Nous montrons ce fichier à tous nos nouveaux ingénieurs et également à tous nos ingénieurs actuels dans un chat de groupe de travail chaque fois que les choses à faire et à ne pas faire sont mises à jour, exhortant vivement tout le monde à le relire (pour rafraîchir les anciennes informations et voir le nouveau).
Vous pourriez dire que tout le monde ne lira pas attentivement. Vous pourriez dire que la majorité l'oubliera juste après la lecture. Et vous auriez raison sur les deux comptes. Cependant, vous ne pouvez pas nier le fait que quelque chose restera dans la tête de quelqu'un. Et ça suffit. Dans l'expérience Citymobil, les ingénieurs prennent ce dossier très au sérieux et les situations où certaines leçons ont été oubliées se sont produites très rarement. Le fait même que la leçon ait été oubliée peut être considéré comme un problème; nous devons tirer une conclusion et analyser les détails pour trouver le moyen de changer quelque chose à l'avenir. Ce type de fouille conduit à des libellés plus précis et plus précis à faire et à ne pas faire.
À retenir de la panne décrite ci-dessus: créer un fichier de choses à faire et à ne pas faire; écrivez tout ce que nous y avons appris, montrez le fichier à toute l'équipe, demandez à chaque nouveau venu de l'étudier et encouragez les gens à poser des questions.
Conseil général que nous avons tiré de l'examen des pannes: nous ne devons pas utiliser une combinaison de mots "merde arrive". Dès que vous le dites à haute voix, tout le monde décide que rien ne doit être fait, aucune conclusion n'est nécessaire car les humains ont toujours fait des erreurs, font des erreurs maintenant et le feront à l'avenir. Par conséquent, au lieu de dire cette phrase, vous devriez tirer
une conclusion précise. Une conclusion - est peut-être un petit mais toujours un pas vers la direction de l'amélioration du processus de développement, des systèmes de surveillance et des outils automatisés. Ces petites étapes se traduisent par un service plus stable!
7. Au lieu d'épilogue
Dans d'autres parties, je vais parler des types de pannes dans l'expérience Citymobil et entrer dans les détails de chaque type de panne; Je vais également vous parler des conclusions que nous avons tirées sur les pannes, comment nous avons modifié le processus de développement, quelle automatisation nous avons introduite. Restez à l'écoute!