
Con este artículo, abro un ciclo corto de dos artículos en el que describiré en detalle cómo logramos aumentar la estabilidad de los servicios de Citymobil varias veces durante varios meses. El artículo comienza con una historia sobre nuestro negocio, sobre la tarea, sobre la razón de la aparición del problema del aumento de la estabilidad y sobre las limitaciones. Citymobil es un agregador de taxis de rápido crecimiento. En 2018, creció más de 15 veces en el número de viajes exitosos. En algunos meses, el crecimiento superó el 50% en comparación con el mes anterior.
El negocio creció a pasos agigantados (y sigue creciendo): la carga en los servidores, el tamaño del equipo y la frecuencia de despliegues han aumentado. Junto con esto, aparecieron nuevas amenazas a la estabilidad del servicio. La compañía enfrentó la tarea más importante: no detener el crecimiento del negocio para aumentar la estabilidad. En este artículo, le contaré cómo logramos realizar esta tarea en poco tiempo.
1. Declaración del problema: ¿qué es exactamente lo que queremos mejorar?
Antes de mejorar algo, debe aprender a medirlo para comprender claramente si hay una mejora. Cuanto más se acerque el valor medido a los términos favorables para los negocios, mejor. Porque cuanto mayor sea la probabilidad de que mejoremos lo que el negocio realmente necesita. Desde el punto de vista de su éxito, el parámetro más importante para nosotros es el número de viajes completados con éxito (en adelante, brevemente, el número de viajes). Es precisamente por este parámetro que los inversores nos evalúan cuando toman una decisión sobre las inversiones. Cuantos más viajes, más costosa es la empresa.
Algunos viajes generan ganancias, otros, pérdidas. Pero todos los viajes son igualmente importantes para nosotros, incluso no rentables, porque nos permiten aumentar la participación en el mercado (de hecho, la pérdida en los viajes es una tarifa por aumentar la participación en el mercado). Por lo tanto, cada viaje adicional recibido es bueno y cada viaje perdido es malo. Todos los viajes son iguales en términos de éxito empresarial.
De aquí obtuvimos un criterio comprensible para medir la estabilidad: el número de viajes perdidos son viajes que claramente perdimos debido a problemas técnicos. Un problema técnico significa, por ejemplo, un error en el código, un error número 500, un bloqueo en la infraestructura, una integración interrumpida con un servicio asociado (por ejemplo, mapas de Google).
2. ¿Cómo contar los viajes perdidos?
Los viajes perdidos son a veces fáciles de calcular, a veces difíciles. Por ejemplo, en el caso de una denegación completa de servicio, cuando nada funciona (pah-pah-pah), es muy fácil calcular los viajes perdidos. Conocemos el gráfico de tendencia del número de viajes antes de la caída, vemos la tendencia de este gráfico después de la caída, completamos la línea entre el punto cuando comenzó simple y el punto cuando terminó. El área del gráfico del número de viajes bajo esta línea completa es viajes perdidos.
En el siguiente gráfico, la línea negra muestra viajes en un día determinado y la línea verde muestra viajes hace una semana. El eje X es el tiempo. En el eje Y, el número de viajes en un cierto intervalo de tiempo alrededor del punto X. Un pico claro se ve hacia abajo en forma de un triángulo de ángulo agudo. El área de este triángulo es el número de viajes perdidos. Por supuesto, esta es una cantidad aproximada, porque el gráfico es fluctuante, pero entendemos que incluso una precisión del 10-20% es suficiente para que podamos estimar la escala del accidente para un negocio.

Si simple no es completo, sino parcial (también, pah-pah-pah), entonces el cálculo es un poco más complicado. Por ejemplo, si hay un error debido al cual el 10% de los pedidos nunca se distribuyen en automóvil, entonces vemos una falla en el horario de viaje y luego un rebote (después de corregir el error). En una situación similar, los viajes perdidos son el área limitada por la línea de tendencia; desde abajo, el horario real del número de viajes, a la izquierda, la línea vertical del comienzo del tiempo de inactividad, a la derecha, la línea vertical del final del tiempo de inactividad.
El gráfico a continuación muestra que el pico más bajo no es tan obvio, pero la presencia de viajes durante la semana anterior sin un pico más bajo ayuda a comprender que un pico más bajo es una pérdida. Además, una comparación de los viajes para el día actual y el mismo día de la semana a la semana anterior deja en claro que el pico más a la derecha no son los viajes perdidos, sino un fracaso habitual en este momento del día, porque se correlaciona con la semana anterior.

Por lo general, es difícil construir una línea de tendencia, porque El gráfico de diente de sierra. En este caso, la comparación semana a semana nos ayuda. Si dibuja dos líneas en el mismo gráfico, la última semana y la actual, entonces resulta que ambas curvas más o menos tienen una forma similar, pero solo difieren en que una está por encima de la otra (la semana actual habitual es más alta que la anterior, aunque hay excepciones). La comparación de semana a semana es importante, porque cada día de la semana, debido a diferentes circunstancias, tiene un formulario de horario diferente. Mirando el gráfico de semana a semana, puede comprender dónde podría estar la línea de tendencia de los viajes de hoy.
Obviamente, un viaje perdido en sí mismo es un problema mucho mayor que un solo viaje perdido. Un cliente que quiere irse de una manera u otra se irá, por ejemplo, usará un servicio competitivo y posteriormente no podrá regresar a nosotros, o solo volverá cuando un competidor lo decepcione, lo cual es poco probable, porque Los competidores son muy fuertes. Además, incluso si un competidor decepciona al cliente, no es un hecho que regrese, porque todo se verá en su cabeza para que todos tengan un mal servicio, y no tiene sentido saltar sobre los competidores.
Es decir, un viaje perdido debido a problemas técnicos significa, de hecho, algunos viajes perdidos.
Para no confundirnos en términos, llamamos a los viajes perdidos directamente debido a un problema técnico,
viajes perdidos primarios y viajes perdidos por dejar al competidor,
viajes perdidos secundarios .
Idealmente, para calcular el daño total a un negocio de un viaje perdido principal, debe comprender cuánto generó el viaje perdido secundario. Es decir es necesario multiplicar el número de viajes perdidos iniciales por un cierto coeficiente
K , que se puede calcular sobre la base de la frecuencia promedio de uso del servicio y el tiempo promedio de devolución del usuario después de dejar al competidor.
Bajo el supuesto de que el coeficiente
K no cambia mucho con el tiempo, para comprender la tendencia de la pérdida de viaje, es suficiente considerar los viajes perdidos primarios y tratar de reducir su número, ya que la relación de viajes perdidos primarios período a período será la misma que la relación de viajes perdidos secundarios período a período periodo Ejemplo: si perdimos 1000 viajes primarios el mes pasado, los viajes secundarios perdimos 1000 *
K , y en total perdimos 1000 * (1+
K ). Si, además, en el mes actual perdimos 500 viajes primarios, luego los viajes secundarios perdimos 500 *
K , y en total perdimos 500 * (1+
K ). En este caso, independientemente del valor del coeficiente
K, comenzamos a perder viajes 1000 * (1+
K ) / (500 * (1+
K )) = 2 veces menos.
Incluso si el coeficiente
K cambia con el tiempo, es decir es una función del tiempo K (t), entonces todavía estamos interesados en reducir el número de viajes perdidos primarios. Porque si K (t) crece con el tiempo, entonces estamos más obligados a hacer esfuerzos para perder menos viajes primarios, porque el daño de perder cada uno es mayor y mayor. Por otro lado, si K (t) disminuye con el tiempo, esto significa que, por alguna razón, los usuarios son cada vez más leales a nosotros, a pesar del mal servicio, lo que significa que simplemente debemos cumplir sus expectativas.
Total: estamos luchando por una disminución constante en los viajes perdidos primarios.
3. Ok, consideramos los viajes perdidos. Que sigue
Armados con una herramienta comprensible para medir los viajes perdidos, pasamos a la parte más interesante: ¿cómo hacerlo para reducir las pérdidas? Y aunque no frena el crecimiento actual! Dado que subjetivamente nos pareció que la mayor parte de los problemas técnicos debido a los viajes que se pierden están relacionados con el backend, decidimos ante todo prestar atención al proceso de desarrollo del backend. Mirando hacia el futuro, diré que resultó de esa manera: el backend se ha convertido en el principal campo de batalla para los viajes perdidos.
4. Cómo funciona el proceso
Los problemas generalmente ocurren debido a la transferencia de código y otras acciones manuales. Los servicios que nunca cambian y nunca se tocan, a veces también fallan, pero esta excepción es solo una regla de confirmación.
La excepción más divertida en mi experiencia fue el siguiente servicio. Cuando trabajé en RBC en 2006 (¡Dios, qué edad tengo!), Luego, en uno de los servicios de correo de RBC había una puerta de enlace a través de la cual pasaba todo el tráfico y que verificaba que las direcciones IP estuvieran en la lista negra. El servicio funcionó en FreeBSD, y funcionó correctamente. Pero un día, dejó de trabajar. Adivina por qué? Un disco se derrumbó en esta máquina (bloques defectuosos acumulados, acumulados y acumulados). Se derrumbó 3 años antes de la denegación de servicio en el servicio (!). Y todo vivía con un disco disperso. Y luego el "frach", por cualquier motivo desconocido para ella por los motivos de Phryakhov, decidió recurrir repentinamente a un disco desmoronado y finalmente congelarse. Estoy seguro de que Linux no haría eso. Pero este es un holivar separado.
Para resumir lo anterior, los problemas se deben a la intervención manual. Una vez en mi infancia, a la edad de 10-12 años, en uno de mis viajes al bosque, escuché de mi padre una frase que recordé toda la vida: "para que la fogata no se apague, simplemente no es necesario tocarla". Creo que muchos de nosotros recordamos los momentos en que arrojamos leña a un fuego que ya ardía y se apagó por alguna razón desconocida.
El resultado final: los problemas se crean mediante acciones manuales de una persona, por ejemplo, arrojar leña a un fuego que ya arde bien, que corta el oxígeno y extingue un fuego, o al extender el código con errores en la producción. Por lo tanto, para comprender la causa de los problemas en los servicios, debe comprender exactamente cómo ocurre el despliegue y cómo funciona el proceso de desarrollo.
El proceso se centró completamente en el desarrollo rápido y se organizó de la siguiente manera:
- 20-30 lanzamientos por día;
- los desarrolladores se implementan ellos mismos;
- prueba rápida en un entorno de prueba por parte del desarrollador;
- pruebas mínimas automatizadas / unitarias, revisiones mínimas.
Los desarrolladores en las condiciones más difíciles, de hecho, sin áreas traseras cubiertas frente al control de calidad, con una gran cantidad de tareas productivas y experimentos importantes para los negocios, trabajaron lo más enfocado y coordinado posible, resolvieron problemas complejos de manera simple, no permitieron que el código "creciera", entendieron bien los problemas comerciales , muy responsablemente a los cambios, retrocedió rápidamente el inactivo. Citymobil no es único aquí. Hace 8 años en Mail.ru Mail, cuando vine a trabajar allí, había una situación similar. Y también comenzamos Mail.ru Cloud de forma rápida y sencilla, sin reverencias. Y ya posteriormente cambiaron los procesos para lograr una mayor estabilidad.
Seguramente, lo notaste por tu cuenta: cuando nadie te cubre la espalda, cuando solo estás solo con la producción, cuando se aplasta una enorme carga de responsabilidad, haces milagros. Yo mismo tuve tal experiencia (aún más hardcore). Érase una vez, en el siglo pasado (estimación, Internet ya estaba en el siglo pasado, me sorprende cuando lo recuerdo), trabajé como el único desarrollador del servicio de correo newmail.ru, lo implementé yo mismo y también probé la producción. a ti mismo a través de
if (!strcmp(username, “danikin”)) { … some new code… }
:-) Por lo tanto, esta situación está cerca de mí.
No me sorprendió si supiera que con un enfoque tan simple "sobre la rodilla" comenzaron muchas startups, tanto exitosas como infructuosas, pero impulsadas por la misma pasión: centrarse en el rápido crecimiento del negocio y la captura del mercado.
¿Por qué fue el proceso específicamente en Citymobil? Inicialmente, había pocos desarrolladores. Trabajaron en la empresa durante mucho tiempo y tenían una buena comprensión del código y los negocios. Los lanzamientos fueron varias veces al día. Los errores fueron extremadamente raros. El proceso funcionó perfectamente para esas condiciones.
5. ¿Por qué un buen proceso amenazó la estabilidad?
Con la creciente inversión en el proyecto, hicimos nuestros planes de productos más agresivos y comenzamos a contratar a muchos desarrolladores. El número de lanzamientos en la producción aumentó, pero se esperaba que su calidad cayera, porque los nuevos muchachos profundizaron en el sistema y la esencia del negocio en condiciones de combate. Con un aumento en el número de desarrolladores, la estabilidad comenzó a caer no solo linealmente, sino de forma cuadrática (el número de implementaciones creció linealmente, y la calidad del despliegue promedio también cayó linealmente; "linealmente" * "linealmente" == "cuadráticamente").
Era obvio que era imposible dejar el proceso de esta forma. Simplemente no fue encarcelado bajo nuevas condiciones. Pero fue necesario cambiarlo sin perjuicio del tiempo de comercialización, es decir, con la preservación de 20-30 lanzamientos por día (y con un aumento en su número en proporción al tamaño del equipo). De hecho, fue en un gran número de lanzamientos que se hizo todo el punto. Crecimos rápidamente, establecimos muchos experimentos, evaluamos rápidamente sus resultados y establecimos nuevos experimentos. Probamos rápidamente hipótesis de productos y negocios, las estudiamos y presentamos nuevas hipótesis, que nuevamente probamos rápidamente, etc. No queríamos reducir este ritmo en ningún caso. Además, querían aumentarlo y aumentar la velocidad de contratación de desarrolladores. Es decir nuestras acciones dirigidas al crecimiento empresarial crearon una amenaza para la estabilidad, pero no queríamos corregir estas acciones de ninguna manera.
6. Ok, la tarea está clara, el proceso está claro. Que sigue
Con experiencia en Mail.ru Mail y Mail.ru Cloud, donde la estabilidad desde algún punto se puso a la vanguardia, donde los despliegues una vez por semana, la funcionalidad detallada y los casos de prueba descritos en detalle, todo está cubierto con pruebas automáticas y unitarias, el código se revisa al menos una vez y, a veces, tres veces, me encontré con una situación completamente nueva.
Parece que todo es simple: repita el proceso en Citymobil como en Mail o la nube y aumente la estabilidad del servicio. Pero, como en esa broma obscena, hay matices: a) los despliegues en Mail / Cloud se llevan a cabo una vez por semana, y no 30 veces al día, y en Citymobil no queríamos sacrificar la frecuencia de los lanzamientos, b) en Mail / Cloud todo el código cubierto por pruebas automáticas / unitarias, y en Citymobil no teníamos tiempo ni recursos para esto, todas las fuerzas del desarrollo del backend fueron elegidas para probar hipótesis y mejoras de productos. Al mismo tiempo, no había suficientes desarrolladores de back-end, incluso a altas velocidades de contratación (gracias especiales a HR Citymobil: ¡estos son los mejores recursos humanos del mundo! Creo que habrá un artículo separado sobre nuestro proceso de recursos humanos), es decir, no había forma de participar en pruebas y revisiones estrictas sin frenar.
7. Cuando no sabes qué hacer, aprende de los errores
Entonces, ¿qué hemos hecho mágicamente en Citymobil? Decidimos aprender de los errores. El método para mejorar el servicio a través del aprendizaje de los errores es tan antiguo como el mundo. Si el sistema funciona bien, entonces está bien. Si el sistema funciona con errores, entonces esto también es bueno, porque puede aprender de estos errores. Eso suena facil. Hacer ... también es simple. Lo principal es establecer una meta.
¿Cómo estudiamos? Comenzamos registrando escrupulosamente la información sobre cada accidente mayor y menor. Francamente, inicialmente no quería hacer esto, porque esperaba un milagro y pensé que los accidentes se detendrían por sí mismos. Por supuesto, nada se detuvo. Nuevas realidades exigían despiadadamente el cambio.
Comenzamos a registrar todos los accidentes en una tabla común de Google. Para cada accidente, se proporcionó la siguiente información breve:
- fecha, hora, duración;
- causa raíz
- lo que hicieron para resolver el problema;
- impacto en el negocio (número de viajes perdidos, otros efectos);
- conclusiones
Para accidentes grandes, creamos archivos grandes separados con descripciones detalladas minuto a minuto, desde el momento en que comenzó el accidente hasta el momento de su finalización: lo que hicimos, las decisiones que tomamos (por lo general, estas descripciones se llaman análisis post mortem). Y en la tabla general agregamos enlaces a dicha autopsia.
El propósito de este archivo era uno: sacar conclusiones, cuya implementación reducirá las pérdidas de viaje. Además, era muy importante formular con precisión cuál es la "causa raíz" y cuáles son las "conclusiones". Estas palabras son entendibles en sí mismas. Pero todos entienden a su manera.
8. Un ejemplo de un error en el que aprendieron
La causa raíz es la eliminación de la cual evitará accidentes similares en el futuro. Y las conclusiones son cómo eliminar la causa raíz (o reducir la probabilidad de que ocurra).
La causa raíz es siempre más profunda de lo que parece. Las conclusiones son siempre más complicadas de lo que parecen. Para no calmarse y detenerse en lo que parece ser, uno siempre debe estar insatisfecho con la causa raíz supuestamente encontrada y siempre estar insatisfecho con las conclusiones alegadas. Este descontento crea fervor para su posterior análisis.
Déjame darte un ejemplo: desplegué el código, todo cayó, retrocedió, todo funcionó. ¿Cuál es la causa raíz?
Despliegue , usted dice. Si no fuera así, no habría accidente. Entonces, ¿cuál es la conclusión: no implementar? Mala conclusión (perjudicial para los negocios, para ser precisos). Es decir, lo más probable es que esta no sea la causa raíz, debe profundizar más.
Estirar con un error . ¿La causa raíz? Digamos ¿Cómo arreglarlo? Por pruebas, dices. Que pruebas Por ejemplo, una regresión completa de toda la funcionalidad. Esta es una buena conclusión, recuérdalo. Pero la estabilidad debe mejorarse aquí y ahora, mientras no haya una regresión completa. Necesito cavar aún más profundo.
Despliegue con un error que ocurrió debido al hecho de que depuramos la impresión en una tabla en la base de datos, la cargamos sin medida y la base de datos se rompió bajo carga . Esto ya es más interesante. De inmediato queda claro que incluso una prueba de regresión completa no lo salvará de este problema. Después de todo, la base de prueba no tendrá la misma carga que la producción.
¿Cuál es la causa raíz de este problema, si profundiza aún más? Para averiguarlo, hablamos con el desarrollador. Resultó que estaba acostumbrado al hecho de que la base hace frente a las cargas. Pero en las condiciones del rápido crecimiento del proyecto, la base se manejó ayer, pero hoy ya no está allí. Pocos de nosotros hemos trabajado en proyectos que están creciendo al 50% de mes a mes. Por ejemplo, para mí este es el primer proyecto de este tipo. Después de sumergirse en tal proyecto, comienza a darse cuenta de las nuevas realidades. Hasta la primera vez que te encuentres con algo, nunca sabrás lo que sucede.
El desarrollador sugirió inmediatamente la solución correcta a la causa de la caída: depurar la impresión en un archivo, escribir el archivo fuera de línea por cron en la base de datos en una secuencia con resbalones. Si hay demasiada impresión de depuración, entonces la base de datos no se acostará, solo la información de depuración aparecerá fuera de tiempo. Obviamente, este desarrollador ya aprendió de su error y no lo repetirá en el futuro. Pero otros desarrolladores también necesitan averiguar sobre esto. Como? Necesito decirles ¿Cómo hacer que se escuche? Cuénteles toda la historia de principio a fin, explique a qué condujo e inmediatamente sugiera cómo hacerlo, así como escuche sus preguntas y responda.
9. ¿Qué más puedes aprender de este error, o qué hacer y qué no hacer?
Entonces, continuamos analizando este accidente. La compañía está creciendo rápidamente, llegan nuevos empleados. ¿Cómo van a aprender de este error? ¿Decirle a cada nuevo empleado? Obviamente, habrá más y más errores: ¿cómo hacer que todos aprendan de ellos? La respuesta es casi obvia: ¡obtenga un archivo de qué hacer y qué no hacer (leer como "doos y donts")! En una traducción gratuita al ruso, lo que se debe y no se debe hacer significa "lo que es bueno y lo que es malo". En este archivo escribimos todas las conclusiones sobre el tema del desarrollo. Mostramos el archivo a todos los nuevos empleados, y también lo mostramos en el chat general de los desarrolladores cada vez que se actualiza el archivo, y amablemente les pedimos a todos que lo lean nuevamente (para que podamos actualizar el conocimiento anterior y ver el nuevo).
Dirás que no todos leerán con cuidado. Dirás que muchos lo olvidarán inmediatamente después de leer. Y tendrás razón las dos veces. Pero no negarás que alguien tendrá algo en la cabeza. Y esto ya está bien. Según la experiencia de Citymobil, los desarrolladores toman muy en serio este archivo, y los casos en que se olvidaron algunas lecciones fueron extremadamente raros. Por cierto, el hecho mismo de que se olvidó la lección puede considerarse un problema y se puede sacar una conclusión, es decir, comprender los detalles y comprender cómo cambiar el proceso para el futuro. Muy a menudo, tal excavación conduce a una redacción más precisa y clara en lo que se debe y no se debe hacer.
Conclusión del accidente descrito anteriormente: cree un archivo de qué hacer y qué no hacer, escriba lo que aprendió en él, muestre el archivo a todo el equipo y solicite a todos los recién llegados que lo estudien.
A partir del consejo general que entendimos en el análisis de accidentes: no utilice la frase "factor humano". Tan pronto como diga esto, todos lo entienden de inmediato, de modo que no se necesita hacer nada, no se necesitan conclusiones, la gente estaba equivocada, equivocada y estará equivocada. Por lo tanto, en lugar de pronunciar esta frase, es necesario sacar una
conclusión específica . Conclusión: este es al menos un pequeño pero pequeño paso para cambiar el proceso, mejorar el monitoreo y mejorar las herramientas automáticas. ¡Con pasos tan pequeños se cose la estructura del servicio estable!
10. En lugar de un epílogo
En la
segunda parte, le contaré sobre los tipos de accidentes de acuerdo con la experiencia de Citymobil y profundizaré en los detalles de cada tipo de accidente, así como también qué conclusiones sacamos de los accidentes, cómo cambiamos el proceso, que introdujo la automatización. ¡Lo más interesante en la segunda parte! Estén atentos!