Ingeniería del caos

Lo último que desea ver durante la depuración de código es el caos . Pero, ¿qué pasa si este caos es controlado y lanzado por las manos del desarrollador mismo? Por qué organizar deliberadamente las turbulencias en el buen funcionamiento de su aplicación, cómo lograr la tranquilidad al liberar funciones importantes y dónde es útil la práctica de la ingeniería del caos , lea PavelOsipov en la conversación entre el podcast líder de AppsCast y Pavel Osipov.



Alexey Kudryavtsev: ¡Hola a todos! Hoy, nuestro invitado es Pavel Osipov de Mail.ru Cloud, con quien hablaremos sobre la ingeniería del caos.

Pavel Osipov: ¡Hola a todos! Durante seis años he gestionado el desarrollo de Mail.ru Cloud. Durante este tiempo, hemos acumulado muchas prácticas de pruebas económicas, y una de ellas es la ingeniería del caos. Esta práctica le permite realizar una serie de experimentos controlados para identificar el estado de su sistema en un entorno hostil. Según los resultados de estos experimentos, obtienes información útil. Por ejemplo, es poco probable que vea regularmente cómo se comporta el sistema en una red inestable. Si su usuario viaja a menudo en el metro o descansa en el entorno wifi de un hotel, la red no es tan estable como en el lugar de trabajo del programador. Después de cada una de mis vacaciones en el mar, traigo una "cartera" completa de registros sobre lo que salió mal con la aplicación.

Personalmente, el caos manual de cría me permite obtener una dosis adicional de confianza de que todo saldrá bien, incluso si todo está mal fuera de la aplicación.

Hay situaciones en las que confío más en el caos manual que en las pruebas automáticas.

Viendo la raíz del caos


Alexei Kudryavtsev: ¿De dónde vienen las raíces de esta práctica?

Pavel Osipov: Esta es una práctica de servidor, donde hay muchos más problemas. Estamos acostumbrados al concepto de deuda técnica, y en Occidente también existe una deuda oscura , una deuda oculta que surge inevitablemente en sistemas complejos. A diferencia de la deuda técnica, donde conscientemente tomamos prestado el tiempo del futuro del presente, la deuda oculta es invisible en la etapa de creación del sistema. Ocurre en la unión de componentes o hardware y software y puede conducir a una cascada de problemas: algo se descompone en un componente, se superpone a otro, y ahora todo el sistema yace.

Por ejemplo, en 2016, debido al cierre de la base de datos en cascada, 2.5 horas yacen en Facebook. Luego, el sistema que verificó la validez de los archivos de configuración comenzó a eliminarlos por error, no solo en el subsistema de almacenamiento en caché, sino también en la base de datos que era la fuente principal.

Me gusta mucho la entrevista con Oleg Anastasiev de Odnoklassniki sobre la realización de ejercicios para prevenir accidentes de infraestructura. Tienen tres centros de datos, que deberían estar en alerta las 24 horas del día, los 7 días de la semana, pero una vez por trimestre se produce algún tipo de falla. Realizan tales ejercicios en producción. Por un lado, esto parece aterrador, porque si sucede algo impredecible, todo el centro de datos caerá y no estará disponible en el producto. Pero, por otro lado, este proceso está controlado y si algo sale mal, inmediatamente lo verá, lo detendrá y todo se restaurará. Si esto sucede en condiciones de vida de combate, entonces volver a encenderlo simplemente no funciona, y el análisis de los motivos del apagado se prolongará durante mucho tiempo.

Los beneficios del caos en el desarrollo móvil


Daniil Popov: Hasta ahora, estamos hablando del desarrollo del servidor, donde los microservicios son populares y son posibles los cortes en cascada. ¿Puedes dar más ejemplos de qué verificar a través de la ingeniería del caos en el desarrollo móvil?

Pavel Osipov: Mi ejemplo favorito es el registro de aplicaciones. En condiciones de prueba, nuestras acciones pueden ser muy suaves con respecto a la aplicación: entramos en la configuración de la cuenta, hicimos clic en el botón "salir", la aplicación salió y, al ver la pantalla de inicio de sesión, todo parece estar bien. Los usuarios a menudo tienen situaciones más exóticas. Por ejemplo, el cliente cambió la contraseña a través de la interfaz web o se produjo un gran número de registros en otros dispositivos y se reemplazó el token de actualización. Este registro no se produce en la ventana con la cuenta de usuario, sino, por ejemplo, en el momento del visor de fotos a pantalla completa.

Encontramos muchas situaciones en las que iniciar sesión en diferentes lugares de la aplicación conlleva consecuencias tales como pérdidas de memoria. El mismo espectador con un bloque de finalización podría obtener un servicio vital, que finalmente se filtró.

Simulamos condiciones usando la ingeniería del caos. El sistema tiene un servicio que, de forma transparente para los servicios de aplicaciones de alto nivel, actualiza el token de acceso de la aplicación utilizando el token de actualización de la aplicación. Introdujimos el caos en el que el servicio, en lugar de actualizar el token, con un cierto grado de probabilidad lo estropea, y cada desarrollador encuentra un registro varias veces al día en un lugar inesperado.

Gracias a esto, descubrimos un comportamiento interesante de UIKit en iOS: si, cuando se resalta un ViewController rooteado, otra ventana se bloquea modalmente desde la ventana, entonces el ViewController rooteado pierde y permanece en el sistema para siempre. Si al mismo tiempo el ViewController tenía un enlace a servicios que, de acuerdo con la lógica de la arquitectura, deben existir en el sistema en una instancia, entonces los problemas no pueden evitarse. Por ejemplo, la nube tiene un servicio de carga automática de fotos, y si dos de estos servicios permanecen en el sistema, harán un trabajo innecesario y colocarán la batería del dispositivo dos veces más rápido de lo que debería.

Otro caso curioso. Cuando apareció iOS 8, hubo problemas con las extensiones: en algunos dispositivos, cuando se otorgaron todos los permisos en la configuración de la aplicación, al principio el sistema declaró que la aplicación no tiene acceso al grupo de aplicaciones compartidas.

Tipologia del caos


Daniil Popov: el caos se introduce automáticamente en el sistema en función de su interés o una configuración, pero ¿necesita una persona una mirada para comprender qué salió mal?

Pavel Osipov: el caos es diferente: tanto manual como automático. En el caso del sistema operativo, que decía que la aplicación no tenía acceso al grupo de aplicaciones compartidas, y las extensiones no podían acceder a los recursos compartidos y a la base de datos, se utilizó el caos manual, que se activó mediante una marca de verificación en la configuración del sistema de la aplicación. Esto podría ser modelado fácilmente por los chicos del equipo de control de calidad.

Hay caos automatizado. En particular, estos son errores que se modelan a partir de los microservicios de nuestro backend y el caos asociado con la actualización del token. Las consecuencias son diferentes. El diseño recorrido se puede determinar a través de la observación visual. Hay lugares que le permiten detectar anomalías en modo automático. Por ejemplo, en nuestra aplicación, las pérdidas de memoria se detectan automáticamente. Hay dos contenedores de IoC en el sistema. Un administrador es la vida útil de los servicios globales, que coincide con la vida útil de la aplicación en sí, otro contenedor es el administrador de los servicios que coinciden en el tiempo con el usuario. Cada contenedor de IoC, al crear un servicio, verifica que exista en una instancia.

Volvamos al ejemplo con los registros. En algún lugar, se produjo un inicio de sesión repentino y el desarrollador volvió a ingresar a la cuenta para continuar trabajando. En este punto, el contenedor IoC informa que se ha producido una pérdida de memoria, y el servicio, que en teoría debería existir en una instancia, se detecta nuevamente.

¿Cuándo es el tiempo del caos?


Alexei Kudryavtsev: ¿Qué sirvió como detonante para la implementación de la práctica?

Pavel Osipov: Llegamos a esto a través de la necesidad de reducir el costo de las pruebas. ¿Cómo se puede lidiar con los mismos problemas del razlogin? Puede escribir pruebas unitarias para detectar fugas, puede confundirse y escribir pruebas de IU.

La ingeniería del caos es la práctica más barata, ya que no está vinculada a los casos de los usuarios, sino que actúa automáticamente para todos los casos de los usuarios juntos.

El segundo desencadenante: antes de que se introdujera la práctica, en nuestro informe de bloqueo, a menudo se observaban bloqueos similares con la misma causa raíz. Por ejemplo, que el bloqueo se produjo no por el registro del sistema en el perfil, sino porque el usuario se desplazaba por la galería de fotos en ese momento. Las situaciones son diferentes y es imposible probar todas las combinaciones de razlogins. Así que quería idear algo que automatizara el proceso.

La ingeniería del caos tiene una práctica relacionada: las pruebas mutacionales . En esta práctica, modificamos pequeños fragmentos de código y vemos cómo esto afecta las pruebas. Si, después del cambio, las pruebas se realizan correctamente, significa que para estos fragmentos de código las pruebas no son suficientes.

La diferencia entre la ingeniería de caos y las pruebas de mutación es que no cambiamos automáticamente el código de producción en sí, sino su entorno.

Alexei Kudryavtsev: ¿Podría ser posible localizar la causa y solucionarlo sin la ingeniería del caos?

Pavel Osipov: No hay una razón única que provoque accidentes. Cada caso es único a su manera. Por ejemplo, el botón modal apareció en la parte superior de la ventana, y esto llevó a que se filtró el ruinoso ViewController durante el razlog. No es posible prever todas las combinaciones de jerarquías de ventanas que tenga durante el registro. Caos que diseña patrones localizados en los que ocurren fugas y choques.

Alexei Kudryavtsev: ¿Cuánto tiempo llevas usando esta práctica?

Pavel Osipov: Comenzamos a usarlo al comienzo del proyecto en 2012, porque era necesario desarrollarlo rápidamente, y no se asignó tiempo para pruebas a gran escala. Además, esto no solo es impresionante, sino también una experiencia positiva.

Daniil Popov: Si algo se ha bloqueado en mi aplicación y necesito comenzar una tarea en JIRA, ¿qué puedo arreglar en el futuro? ¿Cómo puedo reproducir esta situación?

Pavel Osipov: No existe una receta universal. La ingeniería de caos se activa en el momento de la depuración de la aplicación y se desactiva en el momento de la compilación de la versión de lanzamiento, por lo tanto, estas situaciones se pueden ver a través de los registros en la consola del entorno de desarrollo, desde donde puede descubrir cómo colocar la tarea en JIRA.

Alexei Kudryavtsev: ¿Está tratando de crear un comportamiento reproducible para que su sistema de caos le notifique sobre los estados problemáticos y sugiera ingresarlo en la configuración al principio para repetir este estado?

Pavel Osipov: Suena cósmico y posiblemente en arquitecturas como Redux. Si la arquitectura le permite registrar todas las acciones que precedieron a eventos críticos, entonces esto es posible. Esto no es así con nosotros. Esto se practicaba cuando trabajaba como programador de servidor en telecomunicaciones. Hubo pruebas que aleatorizaron la entrada al subsistema y verificaron una salida adecuada. Logramos que cuando la prueba con entrada aleatoria bloqueara el sistema, y ​​en el programa que era responsable de probar la automatización, todos los parámetros necesarios de la solicitud de entrada se pospusieron para que pudiera reproducirse.

Aplicar caos en la aplicación


Daniil Popov: ¿Es correcto que tal caos se introduzca en el código a mano?

Pavel Osipov: Sí, nuestro cliente de red tiene una funcionalidad incorporada en la que puede enviar una configuración, que describe el parámetro de caos que debe reproducirse. Basado en la configuración, decide enviar una solicitud de cliente al servidor o responder tonterías por su cuenta. La capa para trabajar con la red es tal que puede personalizar el caos que introduce el microservicio en el backend. No tiene sentido modelar errores en la validez de los datos de autorización si las solicitudes de microservicio no requieren autorización.

No solo aleatorizamos todo, reproducimos el código perfecto, sino que aleatorizamos significativamente lo que el usuario puede reproducir en la vida real.

Alexei Kudryavtsev: ¿Qué asignas al azar aparte de la red y los archivos?

Pavel Osipov: depuramos la práctica de aleatorizar respuestas de puntos finales específicos para modelar el comportamiento y el caos de cada microservicio por separado. Hemos terminado el trabajo de mover el sistema de archivos a subsistemas separados, y estoy tratando de modelar varios tipos de errores cuando una aplicación intenta escribir o leer un archivo. Acceso simulado manualmente al grupo de aplicaciones compartidas en la aplicación, y realmente quiero comenzar a modelar el comportamiento de la aplicación cuando comienza con un espacio en disco extremadamente pequeño, en el que es imposible incluso crear una base de datos.

Alexei Kudryavtsev: ¿ Eso es todo lo que haces?

Pavel Osipov: En principio, sí. Todavía no hemos eliminado todos esos errores que se encontraron utilizando el caos existente. Por supuesto, es interesante aumentar el caos y transferirlo a otros subsistemas, pero entonces no tendremos tiempo para arreglar tanto como el caos encontrará.

¿Dónde está el lugar del caos? Siempre puede encontrar un lugar donde pueda crear otra turbulencia para la aplicación. Es importante construir sobre los problemas. Creamos caos para iniciar sesión porque observamos una gran cantidad de problemas similares.

Si el monitoreo muestra que en otros subsistemas no hay problemas especiales, entonces no tiene sentido pasar tiempo modelando circunstancias imprevistas.

Esto no se aplica a la facturación, donde la operación correcta es importante.

Alexei Kudryavtsev: Por otro lado, no sabemos qué está pasando con los usuarios; esto es un caos en sí mismo, porque no sabes dónde colocarlo o no, y solo tienes que simularlo.

Pavel Osipov: Siempre necesitas mirar el ROI. Por supuesto, puede reproducir los casos más exóticos, pero si son solteros, entonces tal vez no sean críticos, y no tiene sentido modelarlos.

Desafíos de introducir el caos


Alexei Kudryavtsev: ¿Cuál de lo que ya se hizo fue fácil para usted y qué le causó dificultades?

Pavel Osipov: acostumbrarse al caos es inusual para un principiante, ya que esta no es una práctica de uso común. Es difícil adaptarse al hecho de que tiene muchos errores. En casi todas las pantallas, puede obtener un paquete de "quinientos" o "404" incomprensibles, el servidor responde una vez. Solo con el tiempo te acostumbras al hecho de que todo esto es aburrido, y las respuestas del servidor son modeladas por el propio sistema.

Es difícil cuando tienes una característica crítica que ya está en llamas, y necesitas terminarla lo antes posible, y luego el razlogin aparece repentinamente en el lugar de la acumulación de solicitudes. Por ejemplo, necesita hacer la pantalla correctamente y necesita que todas las solicitudes se completen con éxito, y esto es tan improbable que tenga que ir algunas docenas de veces para lograr el estado deseado. En tales casos, deshabilitar el caos se convierte en una contramedida, y es importante no olvidar volver a encenderlo.

Otro punto que causa insatisfacción es el uso del caos en los servicios de infraestructura con una gran cantidad de efectos secundarios.

Daniil Popov: Entonces, ¿los desarrolladores siempre tienen el caos activado de forma predeterminada?

Pavel Osipov: Absolutamente. A veces, cuando ni siquiera te importa el caos y esas situaciones exóticas que él puede reproducir para ti, es molesto. Tienes que soportar, pero siempre puedes ajustar el nivel de caos si tu pantalla está trabajando intensamente con la red. Por otro lado, el caos puede revelar un problema lejos del lugar donde lo está buscando, y no del desarrollador que desarrolla esta función. Sucede que su función, en la que se agrega el caos, conlleva consecuencias que afectan la función de su colega. No sabrá sobre esto si el caos se incluirá solo en un momento particular de desarrollo.

El significado del caos es identificar consecuencias imprevistas en la interacción de una gran cantidad de componentes.

Si incluye el caos de una manera precisa y medida, entonces estos disparos raros pero bien dirigidos serán invisibles.

Daniil Popov: ¿El caos evita la legibilidad del código?

Pavel Osipov: cuando se introduce el caos fuera del sistema, se adhiere al acabado, entonces sí, parece desordenado. Para nosotros, debido a una larga experiencia de uso, el caos está integrado orgánicamente en el sistema y está tan aislado que no lo notas en el código.

Alexei Kudryavtsev: Capturas muchos casos raros, los arreglas y el código está rodeado de muletas. ¿Esto complica la lógica de la aplicación?

Pavel Osipov: Esta es siempre una gran parte de nuestro código, pero de lo contrario no se escriben grandes aplicaciones de producción. Por supuesto, todo depende de la habilidad del desarrollador, que sabe cómo arreglar el código para que no moleste a los ojos.

Pros de introducir el caos


Daniil Popov: ¿Hay algún indicador cuantitativo que haya mejorado después de la introducción de la ingeniería del caos?

Pavel Osipov: Para mí, la métrica más importante es la tranquilidad interior cuando envío una función para liberar.

Alexey Kudryavtsev: La paz no se puede vender a las empresas. ¿Cómo argumentar la introducción de la ingeniería del caos en la empresa?

Pavel Osipov: la ingeniería del caos libera tiempo para los probadores, ya que hay pruebas automáticas. El mismo choque con razlogin después de la introducción de la práctica del caos casi desapareció de nuestra JIRA.

La ingeniería del caos tiene un efecto beneficioso en el ciclo de lanzamiento, ya que obtiene comentarios rápidos. Una cosa es cuando la función finalizada pasa a prueba, y después de mucho tiempo de que se le informa sobre la cantidad de errores encontrados, es completamente diferente cuando tiene un robot probador que funciona en todo el programa de depuración.

Tengo la sensación de que los resultados de las pruebas unitarias son mucho más bajos que el caos activado en un 50% al descargar miles de archivos. Con tal carga, todas las combinaciones más increíbles definitivamente serán reparadas.

¿De quién aprender y por dónde empezar?


Alexei Kudryavtsev: ¿Qué herramientas usaste para esto? ¿Tomó bibliotecas abiertas o escribió y publicó en código abierto?

Pavel Osipov: Hemos publicado una biblioteca de red en código abierto, pero no hay herramientas especializadas. El único que conozco es Netflix Chaos Monkey , que "corre" aleatoriamente a través de la instancia de AWS y los termina, mira para ver si todo salió bien si se extingue un cierto número de contenedores. Creo que escribir configuraciones donde entras en contacto con sistemas adyacentes no requiere una automatización profunda.

Daniil Popov: ¿Dónde puedo leer más sobre la ingeniería del caos?

Pavel Osipov: Primero, el sitio web de Principios del Caos , al que se vinculan todos los recursos sobre este tema. En segundo lugar, los libros Learning Chaos Engineering y Chaos Engineering Observability .

En general, la ingeniería del caos es la práctica del sentido común y el conocimiento fundamental no existe. Siempre necesitas entender dónde inculcar el caos. Al mismo tiempo, ¿el caos es único para cada aplicación? y primero debe comprender lo que debe implementarse con usted.

Alexei Kudryavtsev: ¿Por dónde empezar si todavía decides introducir el caos?

Pavel Osipov: Comience analizando los problemas en el sistema, los bloqueos y por qué surgen. Después de identificar la raíz del mal, debe comprender cómo modelar situaciones que conducen a problemas. Y el tercer paso es introducir cuidadosamente el caos y mantenerlo bajo control.

Alexei Kudryavtsev: Muchas cosas pueden doler en la aplicación, pero ¿cómo priorizar? ¿Dónde mejor no entrometerse?

Pavel Osipov: No hay cosas irreales. La relación de precio y escape es importante. Si hay una API de sistema rica, entonces encapsularlo con sus propios envoltorios es costoso. Si no comprende completamente algo, entonces comenzará a provocar el caos, que es de naturaleza imposible y conducirá a una lucha inútil. Por ejemplo, si todo el UIKit o API de compras está cubierto por el caos.

El caos no es un golpe aleatorio, sino una comprensión clara de situaciones simuladas.

Alexei Kudryavtsev: ¿Cuánto recomienda implementar esta práctica?

Pavel Osipov: generalmente recomiendo comenzar con la introducción de la ingeniería del caos, en lugar de las pruebas unitarias, ya que esta es la práctica más barata.

¿Interesado en la ingeniería del caos? Vea a Pavel Osipov en la AppsConf de otoño en San Petersburgo del 21 al 21 de octubre, donde presentará su nuevo informe sobre bases de datos de valores clave .

Source: https://habr.com/ru/post/464723/


All Articles