
Avec cet article, j'ouvre un court cycle de deux articles dans lequel je décrirai en détail comment nous avons réussi à augmenter la stabilité des services Citymobil plusieurs fois sur plusieurs mois. L'article commence par une histoire sur notre entreprise, sur la tâche, sur la raison de l'apparition du problème de l'augmentation de la stabilité et sur les limites. Citymobil est un agrégateur de taxis à croissance rapide. En 2018, il a augmenté de plus de 15 fois le nombre de voyages réussis. Certains mois, la croissance a dépassé 50% par rapport au mois précédent.
L'activité a progressé à pas de géant (et continue de croître): la charge sur les serveurs, la taille de l'équipe et la fréquence des déploiements ont augmenté. Parallèlement à cela, de nouvelles menaces à la stabilité du service sont apparues. L'entreprise a été confrontée à la tâche la plus importante - ne pas arrêter la croissance de l'entreprise pour accroître sa stabilité. Dans cet article, je vais vous expliquer comment nous avons réussi à réaliser cette tâche en peu de temps.
1. Énoncé du problème: que voulons-nous améliorer exactement?
Avant d'améliorer quelque chose, vous devez apprendre à le mesurer afin de comprendre clairement s'il y a une amélioration. Plus la valeur mesurée est proche de termes favorables aux entreprises, mieux c'est. Parce que plus il y a de chances que nous améliorions ce dont l'entreprise a vraiment besoin. Du point de vue de son succès, le paramètre le plus important pour nous est le nombre de voyages terminés avec succès (ci-après brièvement - le nombre de voyages). C'est précisément par ce paramètre que les investisseurs nous évaluent lorsqu'ils prennent une décision d'investissement. Plus il y a de voyages, plus l'entreprise coûte cher.
Certains voyages font un profit, certains - une perte. Mais tous les voyages sont tout aussi importants pour nous, même non rentables, car ils vous permettent d'augmenter la part de marché (en fait, la perte sur les voyages est un paiement pour augmenter la part de marché). Par conséquent, chaque voyage supplémentaire reçu est bon et chaque voyage perdu est mauvais. Tous les voyages sont égaux en termes de réussite commerciale.
De là, nous avons obtenu un critère compréhensible pour mesurer la stabilité: le nombre de voyages perdus sont des voyages que nous avons clairement perdus en raison de problèmes techniques. Un problème technique signifie, par exemple, un bug dans le code, une 500ème erreur, un crash sur l'infrastructure, une rupture de l'intégration avec un service partenaire (par exemple, Google maps).
2. Comment compter les voyages perdus?
Les déplacements perdus sont parfois faciles à calculer, parfois difficiles. Par exemple, dans le cas d'un déni de service complet, lorsque rien ne fonctionne (pah-pah-pah), il est très facile de calculer les trajets perdus. Nous connaissons le graphique de tendance du nombre de voyages avant l'automne, nous voyons la tendance de ce graphique après l'automne, nous terminons la ligne entre le point où il a commencé simple et le point où il s'est terminé. La zone du graphique du nombre de déplacements sous cette ligne terminée correspond aux déplacements perdus.
Dans le graphique suivant, la ligne noire montre les voyages un certain jour et la ligne verte montre les voyages il y a une semaine. L'axe des X est le temps. Sur l'axe Y, le nombre de déplacements dans un certain intervalle de temps autour du point X. Un pic clair est vu sous la forme d'un triangle à angle aigu. L'aire de ce triangle est le nombre de déplacements perdus. Bien sûr, il s'agit d'un montant approximatif, car le graphique est fluctuant, mais nous comprenons que même une précision de 10 à 20% nous suffit pour estimer l'ampleur de l'accident pour une entreprise.

Si simple n'est pas complet, mais partiel (aussi, pah-pah-pah), alors le calcul est un peu plus compliqué. Par exemple, s'il y a un bug à cause duquel 10% des commandes ne sont jamais distribuées en voiture, alors nous voyons un échec sur le planning de voyage, puis un rebond (après correction du bug). Dans une situation similaire, les déplacements perdus sont la zone délimitée au-dessus par la ligne de tendance; à partir du bas - le calendrier réel du nombre de trajets, vers la gauche - la ligne verticale du début du temps d'arrêt, vers la droite - la ligne verticale de la fin du temps d'arrêt.
Le graphique ci-dessous montre que le pic descendant n'est pas si évident, mais la présence de trajets pour la semaine précédente sans pic descendant permet de comprendre qu'un pic descendant est une perte. En outre, une comparaison des trajets pour la journée en cours et le même jour de la semaine avec la semaine précédente montre clairement que le pic le plus à droite n'est pas des trajets perdus, mais un échec habituel à cette heure de la journée, car il correspond à la semaine précédente.

Il est généralement difficile de construire une ligne de tendance, car le graphique en dents de scie. Dans ce cas, la comparaison d'une semaine à l'autre nous aide. Si vous dessinez deux lignes sur le même graphique - la semaine dernière et la ligne actuelle - il se trouve que les deux courbes plus ou moins sont de forme similaire, mais diffèrent uniquement en ce que l'une est au-dessus de l'autre (la semaine en cours habituelle est plus élevée que la précédente, bien qu'il y ait exceptions). La comparaison d'une semaine à l'autre est importante, car chaque jour de la semaine, en raison de circonstances différentes, a un horaire différent. En regardant le graphique d'une semaine à l'autre, vous pouvez comprendre où pourrait être la ligne de tendance des voyages d'aujourd'hui.
De toute évidence, un voyage perdu en soi est un problème beaucoup plus grave qu'un seul voyage perdu. Un client qui souhaite quitter d'une manière ou d'une autre quittera, par exemple, un service compétitif et ne pourra par la suite nous revenir, ou ne reviendra que lorsqu'un concurrent le décevra, ce qui est peu probable, car les concurrents sont très forts. De plus, même si un concurrent déçoit le client, alors le client n'est pas un fait qu'il reviendra, car tout se ressemblera dans sa tête pour que tout le monde ait un mauvais service, et il ne sert à rien de sauter par-dessus les concurrents.
Autrement dit, un voyage perdu en raison de problèmes techniques signifie, en fait, quelques voyages perdus.
Afin de ne pas être confondu en termes, nous appelons les voyages perdus directement en raison d'un problème technique,
les voyages perdus primaires et les voyages perdus en raison du départ du concurrent,
les voyages perdus secondaires .
Idéalement, pour calculer les dommages totaux subis par une entreprise à partir d'un seul voyage perdu, vous devez comprendre combien il a généré le voyage perdu secondaire. C'est-à-dire il est nécessaire de multiplier le nombre de trajets perdus initiaux par un certain coefficient
K , qui peut être calculé sur la base de la fréquence moyenne d'utilisation du service et du temps moyen de retour de l'utilisateur après avoir quitté le concurrent.
En supposant que le coefficient
K ne change pas beaucoup au fil du temps, pour comprendre la tendance des pertes de voyages, il suffit de considérer les principaux voyages perdus et d'essayer de réduire leur nombre, car le ratio des principaux voyages perdus d'une période à l'autre sera le même que le ratio des voyages secondaires perdus d'une période à l'autre. période. Exemple: si nous avons perdu 1000 voyages primaires le mois dernier, puis les voyages secondaires, nous avons perdu 1000 *
K , et au total, nous avons perdu 1000 * (1+
K ). Si, en outre, au cours du mois en cours, nous avons perdu 500 voyages primaires, puis les voyages secondaires, nous avons perdu 500 *
K , et au total, nous avons perdu 500 * (1+
K ). Dans le même temps, quelle que soit la valeur du coefficient
K , nous avons commencé à perdre des déplacements 1000 * (1+
K ) / (500 * (1+
K )) = 2 fois moins.
Même si le coefficient
K change avec le temps, c'est-à-dire est fonction du temps K (t), alors nous sommes toujours intéressés à réduire le nombre de déplacements primaires perdus. Car si K (t) croît avec le temps, alors nous sommes d'autant plus obligés de faire des efforts pour perdre moins de déplacements primaires, car les dégâts causés par la perte de chacun sont de plus en plus importants. D'un autre côté, si K (t) diminue avec le temps, cela signifie que pour une raison quelconque, les utilisateurs nous sont de plus en plus fidèles, malgré le mauvais service, ce qui signifie que nous devons simplement répondre à leurs attentes!
Total: nous luttons pour une diminution constante des déplacements primaires perdus.
3. D'accord, nous considérons les voyages perdus. Et ensuite?
Armé d'un outil compréhensible pour mesurer les trajets perdus, nous nous tournons vers la partie la plus intéressante - comment le faire pour réduire les pertes? Et sans ralentir la croissance actuelle! Puisque subjectivement il nous a semblé que la part du lion des problèmes techniques à cause desquels les trajets sont perdus est liée au backend, nous avons décidé de faire tout d'abord attention au processus de développement du backend. Pour ce qui est de l’avenir, je dirai que cela s’est avéré comme ça - le backend est devenu le principal champ de bataille pour les voyages perdus.
4. Comment fonctionne le processus
Les problèmes surviennent généralement en raison du roulement de code et d'autres actions manuelles. Les services qui ne changent jamais et ne touchent jamais, échouent parfois aussi, mais cette exception n'est qu'une règle de confirmation.
L'exception la plus drôle de mon expérience était le service suivant. Lorsque je travaillais chez RBC en 2006 (Dieu, quel âge j'ai!), Ensuite, sur l'un des services de messagerie de RBC, il y avait une passerelle par laquelle tout le trafic passait et qui vérifiait les adresses IP pour être sur liste noire. Le service fonctionnait sur FreeBSD et fonctionnait correctement. Mais un jour, il a cessé de travailler. Devinez pourquoi? Un disque s'est effondré sur cette machine (mauvais blocs accumulés, accumulés et accumulés). Émietté 3 ans avant le déni de service dans le service (!). Et tout vivait avec un disque dispersé. Et puis la "brasse", pour une raison qui lui est inconnue par les motifs de Phryakhov, a décidé de se tourner soudainement vers un disque en ruine et finalement de geler. Je suis sûr que Linux ne ferait pas ça. Mais ceci est un holivar séparé.
Pour résumer ce qui précède, les problèmes sont dus à une intervention manuelle. Une fois dans mon enfance, à l'âge de 10 à 12 ans, lors d'un de mes voyages dans la forêt, j'ai entendu de mon père une phrase dont je me suis souvenu toute ma vie: "pour que le feu de joie ne s'éteigne pas, vous n'avez tout simplement pas besoin de le toucher." Je pense que beaucoup d'entre nous se souviennent des moments où nous avons jeté du bois de chauffage dans un feu déjà brûlant et qu'il s'est éteint pour une raison inconnue.
En bout de ligne: les problèmes sont créés par les actions manuelles d'une personne, par exemple, en jetant du bois de chauffage dans un feu déjà bien brûlé, qui coupe l'oxygène et éteint un incendie, ou en déployant du code avec des bogues en production. Par conséquent, pour comprendre la cause des problèmes dans les services, vous devez comprendre exactement comment le déploiement se produit et comment fonctionne le processus de développement.
Le processus était entièrement axé sur le développement rapide et était organisé comme suit:
- 20-30 sorties par jour;
- les développeurs se déploient;
- tests rapides dans un environnement de test par le développeur;
- tests automatisés / unitaires minimaux, révisions minimales.
Les développeurs dans les conditions les plus difficiles, en fait, sans zones arrière couvertes face à l'AQ, avec un énorme flux de tâches productives et d'expériences importantes pour les entreprises, ont travaillé de manière aussi ciblée et coordonnée que possible, ont résolu des problèmes complexes de manière simple, n'ont pas permis au code de «grandir», des problèmes commerciaux bien compris , très responsable des changements, a rapidement annulé le ralenti. Citymobil n'est pas unique ici. Il y a 8 ans dans Mail.ru Mail, quand je suis venu travailler là-bas, il y avait une situation similaire. Et nous avons également lancé Mail.ru Cloud rapidement et simplement, sans faire de révérence. Et déjà changé par la suite les processus afin d'atteindre une plus grande stabilité.
Vous l'avez sûrement remarqué par vous-même: quand personne ne vous couvre le dos, quand vous êtes seul avec la production, quand un énorme fardeau de responsabilité s'écrase - vous faites des miracles. J'ai moi-même vécu une telle expérience (encore plus hardcore). Il était une fois, au siècle dernier (estimation, Internet était déjà au siècle dernier, je suis surpris quand je m'en souviens), j'ai travaillé comme le seul développeur du service de messagerie newmail.ru, je l'ai déployé moi-même et j'ai testé la production moi-même à vous-même via
if (!strcmp(username, “danikin”)) { … some new code… }
:-) Par conséquent, cette situation est proche de moi.
Je ne suis pas surpris si je savais qu'avec une approche aussi simple «à genoux», de nombreuses start-ups ont commencé, à la fois réussies et infructueuses, mais animées par la même passion - se concentrer sur la croissance rapide des entreprises et la conquête du marché.
Pourquoi le processus était-il spécifiquement dans Citymobil? Au départ, il y avait peu de développeurs. Ils ont travaillé dans l'entreprise pendant longtemps et avaient une bonne compréhension du code et des affaires. Les déploiements ont eu lieu plusieurs fois par jour. Les erreurs étaient extrêmement rares. Le processus a parfaitement fonctionné dans ces conditions.
5. Pourquoi un bon processus a-t-il menacé la stabilité?
Avec l'augmentation des investissements dans le projet, nous avons rendu nos plans de produits plus agressifs et avons commencé à embaucher de nombreux développeurs. Le nombre de déploiements sur la production a augmenté, mais leur qualité devrait chuter, car les nouveaux gars se sont plongés dans le système et l'essence même de l'entreprise dans des conditions de combat. Avec une augmentation du nombre de développeurs, la stabilité a commencé à chuter même pas de manière linéaire, mais quadratique (le nombre de déploiements a augmenté linéairement et la qualité du déploiement moyen a également chuté linéairement; "linéairement" * "linéairement" == "quadratique").
Il était évident qu'il était impossible de laisser le processus sous cette forme. Il n'a tout simplement pas été emprisonné dans de nouvelles conditions. Mais il a fallu le changer sans préjudice du time-to-market, c'est-à-dire avec la préservation de 20-30 sorties par jour (et avec une augmentation de leur nombre proportionnellement à la taille de l'équipe). En effet, c'est dans un grand nombre de versions que tout le point a été souligné. Nous avons grandi rapidement, mis en place de nombreuses expériences, évalué rapidement leurs résultats et mis en place de nouvelles expériences. Nous avons rapidement testé des hypothèses de produits et d'affaires, étudié celles-ci et proposé de nouvelles hypothèses, que nous avons à nouveau rapidement testées, etc. Nous ne voulions en aucun cas réduire ce rythme. De plus, ils voulaient l'augmenter et augmenter la vitesse d'embauche des développeurs. C'est-à-dire nos actions visant à la croissance des entreprises ont créé une menace pour la stabilité, mais nous ne voulions en aucun cas corriger ces actions.
6. Ok, la tâche est claire, le processus est clair. Et ensuite?
Ayant de l'expérience dans Mail.ru Mail et Mail.ru Cloud, où la stabilité a été mise en avant, où les déploiements une fois par semaine, décrit en détail les fonctionnalités et les cas de test, tout est couvert par des tests automatiques et unitaires, le code est revu au moins une fois, et parfois trois fois, je suis tombé sur une situation complètement nouvelle.
Il semblerait que tout soit simple: répétez le processus dans Citymobil comme dans Mail ou le Cloud et augmentez la stabilité du service. Mais, comme dans cette blague obscène, il y a des nuances: a) les déploiements dans le Mail / Cloud sont effectués une fois par semaine, et non 30 fois par jour, et dans Citymobil nous ne voulions pas sacrifier la fréquence des versions, b) dans le Mail / Cloud tout le code couvert par des tests auto / unitaires, et dans Citymobil nous n'avions ni le temps ni les ressources pour cela, toutes les forces du développement backend étaient consacrées au test d'hypothèses et à l'amélioration des produits. Dans le même temps, il n'y avait pas assez de développeurs back-end, même à des vitesses de recrutement élevées (merci en particulier à HR Citymobil - ce sont les meilleures RH au monde! Je pense qu'il y aura un article séparé sur notre processus RH), c'est-à-dire qu'il n'y avait aucun moyen de s'engager dans des tests et des revues serrés sans ralentir.
7. Lorsque vous ne savez pas quoi faire, apprenez des erreurs
Alors qu'avons-nous fait comme par magie dans Citymobil? Nous avons décidé d'apprendre des erreurs. La méthode pour améliorer le service en apprenant des erreurs est aussi ancienne que le monde. Si le système fonctionne bien, alors c'est bien. Si le système fonctionne avec des erreurs, c'est également une bonne chose, car vous pouvez apprendre de ces erreurs. Cela semble facile. Faire ... est aussi simple. L'essentiel est de se fixer un objectif.
Comment avons-nous étudié? Nous avons commencé par enregistrer scrupuleusement des informations sur chaque accident majeur et mineur. Franchement, je ne voulais pas vraiment faire ça au départ, car j'espérais un miracle et je pensais que les accidents s'arrêteraient d'eux-mêmes. Bien sûr, rien ne s'est arrêté. De nouvelles réalités exigeaient impitoyablement des changements.
Nous avons commencé à consigner tous les accidents dans une table Google commune. Pour chaque accident, les brèves informations suivantes ont été fournies:
- date, heure, durée;
- cause profonde
- ce qu'ils ont fait pour résoudre le problème;
- impact sur l'entreprise (nombre de voyages perdus, autres effets);
- conclusions.
Pour les accidents majeurs, nous avons créé des fichiers volumineux séparés avec des descriptions détaillées minute par minute, du moment où l'accident a commencé jusqu'au moment de l'achèvement: ce que nous avons fait, quelles décisions nous avons prises (généralement ces descriptions sont appelées analyse post mortem). Et dans le tableau général, nous avons ajouté des liens vers une telle autopsie.
L'objectif de ce dossier était le suivant: tirer des conclusions dont la mise en œuvre réduira les pertes de déplacements. En outre, il était très important de formuler avec précision quelle était la «cause profonde» et quelles étaient les «conclusions». Ces mots sont compréhensibles en eux-mêmes. Mais chacun comprend à sa manière.
8. Un exemple d'une erreur sur laquelle ils ont appris
La cause première est l’élimination de ce qui empêchera des accidents similaires à l’avenir. Et les conclusions sont de savoir comment éliminer la cause profonde (ou réduire la probabilité de son apparition).
La cause profonde est toujours plus profonde qu'il n'y paraît. Les conclusions sont toujours plus compliquées qu'elles ne le semblent. Afin de ne pas se calmer et de ne pas insister sur ce qui semble être, il faut toujours être insatisfait de la cause fondamentale prétendument trouvée et toujours insatisfait des conclusions alléguées. Ce mécontentement crée la ferveur d'une analyse plus approfondie.
Permettez-moi de vous donner un exemple: déployé le code - tout est tombé, annulé - tout a fonctionné. Quelle est la cause profonde?
Déployez -vous, dites-vous. Si elle n'était pas là, il n'y aurait pas d'accident. Alors quelle est la conclusion: ne pas déployer? Mauvaise conclusion (nuisible aux entreprises, pour être précis). Autrement dit, ce n'est probablement pas la cause première, vous devez creuser plus profondément.
Déployez avec un bug . La cause profonde? Disons. Comment y remédier? Par des tests, dites-vous. Quels tests? Par exemple, une régression complète de toutes les fonctionnalités. Ceci est une bonne conclusion, souvenez-vous-en. Mais la stabilité doit être améliorée ici et maintenant, alors qu'il n'y a pas de régression complète. Besoin de creuser encore plus profondément.
Déploiement avec un bogue qui s'est produit du fait que nous avons débogué l'impression dans une table de la base de données, l'avons chargée au-delà de toute mesure et la base de données s'est rompue sous charge . C'est déjà plus intéressant. Il devient immédiatement clair que même un test de régression complet ne vous sauvera pas de ce problème. Après tout, la base de test n'aura pas la même charge que la production.
Quelle est la cause profonde de ce problème, si vous creusez encore plus profondément? Pour le savoir, nous avons discuté avec le développeur. Il s'est avéré qu'il était habitué au fait que la base supporte les charges. Mais dans les conditions de croissance rapide du projet, la base a réussi hier, mais aujourd'hui elle n'est plus là. Peu d'entre nous ont travaillé sur des projets qui augmentent de 50% de mois en mois. Par exemple, pour moi, c'est le premier projet de ce type. Après avoir plongé dans un tel projet, vous commencez à prendre conscience de nouvelles réalités. Jusqu'à la première fois que vous rencontrez quelque chose, vous ne saurez jamais ce qui se passe.
Le développeur a immédiatement suggéré la bonne solution à la cause de la chute: déboguer l'impression dans un fichier, écrire le fichier hors ligne par cron dans la base de données en un seul flux avec des feuillets. S'il y a trop d'impression de débogage, la base de données ne s'allongera pas, seules les informations de débogage y apparaîtront hors du temps. Évidemment, ce développeur a déjà appris de son erreur et ne le répétera pas à l'avenir. Mais d'autres développeurs doivent également en savoir plus. Comment? Besoin de leur dire. Comment le faire entendre? Racontez-leur toute l'histoire du début à la fin, expliquez ce qu'elle a mené et suggérez immédiatement comment le faire, écoutez leurs questions et répondez-y.
9. Que pouvez-vous apprendre d'autre de cette erreur, ou à faire et à ne pas faire
Nous continuons donc d'analyser cet accident. L'entreprise se développe rapidement, de nouveaux employés arrivent. Comment vont-ils apprendre de cette erreur? Dites à chaque nouvel employé? 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 évidente: obtenez un fichier de choses à faire et à ne pas faire (lire «à faire et à ne pas faire»)! Dans une traduction gratuite en russe, l'idiome à faire et à ne pas faire signifie «ce qui est bon et ce qui est mauvais». Dans ce dossier, nous écrivons toutes les conclusions sur le thème du développement. Nous montrons le fichier à tous les nouveaux employés, et le montrons également dans le chat général des développeurs chaque fois que le fichier est mis à jour, et nous demandons à tout le monde de le relire (afin de rafraîchir à la fois les anciennes connaissances et les nouvelles).
Vous direz que tout le monde ne lira pas attentivement. Vous direz que beaucoup oublieront immédiatement après avoir lu. Et vous aurez raison les deux fois. Mais vous ne nierez pas que quelqu'un aura quelque chose en tête. Et c'est déjà bien. Selon l'expérience de Citymobil, les développeurs prennent ce dossier très au sérieux et les cas où certaines leçons ont été oubliées étaient extrêmement rares. Soit dit en passant, le fait même que la leçon ait été oubliée peut être considéré comme un problème et une conclusion peut en être tirée, c'est-à-dire pour comprendre les détails et comprendre comment changer le processus pour l'avenir. Très souvent, ces fouilles conduisent à une formulation plus précise et claire des choses à faire et à ne pas faire.
Conclusion de l'accident décrit ci-dessus: créez un fichier de choses à faire et à ne pas faire, écrivez ce que vous avez appris, montrez le fichier à toute l'équipe et demandez à tous les nouveaux arrivants de l'étudier.
D'après les conseils généraux que nous avons compris dans l'analyse des accidents: ne pas utiliser l'expression «facteur humain». Dès que vous dites cela, ils le comprennent tous immédiatement de sorte que rien ne doit être fait, aucune conclusion n'est nécessaire, les gens ont eu tort, tort et vont se tromper. Par conséquent, au lieu de prononcer cette phrase, il est nécessaire de tirer une
conclusion spécifique . Conclusion - c'est au moins une petite, mais une petite étape pour changer le processus, améliorer la surveillance, améliorer les outils automatiques. À partir de ces petites étapes, le tissu d'un service stable est cousu!
10. Au lieu d'un épilogue
Dans la
deuxième partie, je vais vous parler des types d'accidents selon l'expérience de Citymobil et me plonger dans les détails de chaque type d'accident, ainsi que vous dire quelles conclusions nous avons tirées des accidents, comment nous avons changé le processus, qui a introduit l'automatisation. Le plus intéressant dans la deuxième partie! Restez à l'écoute!