Crear aplicaciones modernas utilizando tecnología sin servidor y servicios gestionados significa que cualquiera puede construir sistemas distribuidos y altamente disponibles sin preocuparse de la infraestructura subyacente. Pero no todo es diversión y juegos. Esta charla que di en AWS re:Invent 2019 con el título «Realizando ingeniería del caos en un mundo sin servidor» explica algunos de los desafíos con serverless, debilidades comunes en las aplicaciones sin servidor, así como los desafíos con el uso de la ingeniería del caos en serverless. Consulta el vídeo.
Inyectar fallos en nuestras funciones
El héroe sin servidor de AWS Yan Cui ha escrito varios artículos sobre la inyección de latencia para AWS Lambda, consulta «¿Cómo podemos aplicar los principios de la ingeniería del caos a AWS Lambda?». (https://theburningmonk.com/2017/10/how-can-we-apply-the-principles-of-chaos-engineering-to-aws-lambda/) y «Aplicación de los principios de la ingeniería del caos a AWS Lambda con la inyección de latencia» (https://hackernoon.com/chaos-engineering-and-aws-lambda-latency-injection-ddeb4ff8d983) de octubre de 2017. Estos artículos explican por qué podemos y debemos utilizar la ingeniería del caos en nuestras aplicaciones sin servidor, además de mostrar ejemplos de cómo hacerlo.
El principal defensor de la arquitectura de los desarrolladores de AWS, Adrian Hornsby, amplió esta idea creando primero una capa Lambda y, más tarde, una biblioteca Python para la inyección de fallos, chaos_lambda (https://github.com/adhorn/aws-lambda-chaos-injection), que ofrece a los desarrolladores una forma más sencilla de comenzar con experimentos de caos para AWS Lambda. Sólo tienes que instalar la biblioteca, envolver tus funciones con el modo de fallo apropiado y ¡ya estás listo para empezar a inyectar fallos!
Para alcanzar el mismo nivel de simplicidad para los desarrolladores de NodeJS, a finales del año pasado creé un paquete NPM llamado failure-lambda (https://github.com/gunnargrosch/failure-lambda). El objetivo de failure-lambda es, en resumen, disponer de una forma sencilla de inyectar fallos en AWS Lambda utilizando varios modos de fallo diferentes. Para hacerlo aún más fácil, decidí utilizar una sola envoltura y, en su lugar, hacer que el modo de fallo fuera seleccionable. Así no tienes que hacer cambios en el código si quieres cambiar entre, por ejemplo, latencia o inyección de excepciones, sólo tienes que cambiar un ajuste.
Como sabemos, serverless no es sólo AWS y la ingeniería del caos para serverless no es sólo AWS Lambda. Por esa razón, ahora también existen las mismas opciones de inyección de fallos para los desarrolladores de NodeJS que construyen sin servidor utilizando Azure Functions y Cloud Functions. Esto con los paquetes NPM failure-azurefunctions (https://github.com/gunnargrosch/failure-azurefunctions) y failure-cloudfunctions (https://github.com/gunnargrosch/failure-cloudfunctions).
Modos de fallo y tasa de fallo
Aunque todo esto empezó con la inyección de latencia, como en los artículos de Yan Cui, la latencia está lejos de ser el único fallo posible que podemos tener en nuestras aplicaciones sin servidor. En fallo-lambda, fallo-azurefunctions y fallo-cloudfunctions hay ahora cinco modos de fallo diferentes entre los que elegir:
Latencia – Inyecta latencia a la función ejecutada, controlada mediante un intervalo mínimo y máximo de milisegundos. Esto puede utilizarse, por ejemplo, para simular la latencia del servicio o para probar y ayudar a establecer tus valores de tiempo de espera.
Excepción – Lanza una excepción en la función. Te ayuda a probar cómo tu aplicación y tu código gestionan las excepciones.
Código de estado – Tu función devolverá un código de estado a elegir, por ejemplo 502 o 404 en lugar del normal 200. Esto te da la posibilidad de probar qué ocurre cuando hay errores.
Espacio en disco – Llenará tu disco temporal de archivos para crear un fallo. Si utilizas un disco para almacenar archivos temporales, puedes probar cómo se comporta tu aplicación si ese disco se llena o no puedes almacenar en él.
Lista negra (cortesía de Jason Barto) – Bloquea las conexiones a los hosts especificados. Utilízalo para simular que los servicios o terceros no están disponibles.
Todos estos modos de fallo se pueden utilizar junto con un índice de fallo que tú establezcas. Por defecto, se inyecta un fallo en cada invocación, pero en realidad, es probable que, por ejemplo, un tercero no esté disponible en el 50% de las llamadas realizadas a ese host o que se lance una excepción en una cuarta parte de las invocaciones. Fijar la tasa te permitirá conseguirlo.