Sistemas distribuidos
Microservicios: ¿una promesa resiliente?
Una aplicación no es resiliente. Es resiliente a algo.
Cristiano Rego Barros
5 min de lectura
Publicado originalmente en Medium
En el escenario actual de la ingeniería de software, la arquitectura de microservicios es uno de los estilos arquitectónicos que más fama ha ganado en la comunidad. Con esa popularidad surgen diversos argumentos a favor de su adopción. Algunos siguen la línea de estos temas:
- «Las aplicaciones con arquitectura de microservicios tienen mejor rendimiento»;
- «Los microservicios aceleran el desarrollo»;
- «La arquitectura de microservicios es resiliente»;
- «La arquitectura de microservicios es tolerante a fallas»;
- «Los microservicios son escalables»;
- «Migrar de monolitos a microservicios resuelve los problemas de disponibilidad».
Al escuchar afirmaciones como estas, el estilo de microservicios resulta muy atractivo. Puede parecer que basta con migrar una aplicación a esta arquitectura, o empezar ya con ella, para tener una aplicación con buen rendimiento, escalable, disponible, resiliente, tolerante a fallas, segura y con alta velocidad de desarrollo.
¿Qué profesional de la ingeniería de software no se sentiría atraído por ese cuento, verdad?
Pero ¿todo esto es cierto? ¿Basta con usar esta arquitectura para lograr todas esas características? Si empiezo mi aplicación con solo dos servicios, ¿será resiliente y tolerante a fallas?
Puedo decirlo de antemano: no, no y no. La simple adopción de la arquitectura de microservicios no transforma una aplicación por sí sola.
Aunque ya adelanté que estas afirmaciones no son ciertas, me gustaría profundizar en estas características y en la relación de cada una con la arquitectura de microservicios. Como son muchas, en este artículo me centraré en «la arquitectura de microservicios es resiliente» y «la arquitectura de microservicios es tolerante a fallas», más precisamente en la característica arquitectónica de resiliencia.
¿Qué es la resiliencia, al fin y al cabo?
Antes de entender más sobre la resiliencia en microservicios, conviene entender qué es la resiliencia y qué significa ser resiliente. Para la física, la resiliencia es la propiedad que tienen algunos cuerpos de volver a su forma original después de haber sido sometidos a una deformación elástica. En sentido figurado, el diccionario la define como la capacidad de recuperarse fácilmente o de adaptarse a la mala suerte o a los cambios.
En el ámbito de la ingeniería y la arquitectura de software, la resiliencia se refiere a la capacidad técnica de las aplicaciones de cumplir sus requisitos de entrega, en la realización de sus actividades, sin verse afectadas por alguna adversidad (interna o externa).
Entonces, ¿por qué la arquitectura de microservicios se consideraría resiliente y tolerante a fallas?
El argumento se basa en la comparación con las arquitecturas monolíticas, en las que los componentes internos están todos agrupados en un único conjunto y sufren una carga llamada acoplamiento.
El acoplamiento actúa porque muchos componentes conviven en un único conjunto, todos conectados, y partes sanas de ese conjunto pueden verse afectadas indirectamente por partes debilitadas.
Como la arquitectura de microservicios promueve el desacoplamiento entre componentes, sería más resiliente y tolerante a fallas parciales que el patrón monolítico.
Siendo así, ¿se puede decir que la arquitectura de microservicios es realmente más resiliente que la monolítica?
La red cobra su precio
No necesariamente. Como primer punto de atención, conviene entender que, en las arquitecturas monolíticas, la mayoría de los componentes internos se comunican en memoria, de forma ligera. En la arquitectura distribuida, en cambio, los componentes suelen comunicarse por la red, una comunicación más pesada y susceptible a fallas.
Las ocho falacias de la computación distribuida, de Peter Deutsch, aportan excelentes puntos para constatar que esta arquitectura no será resiliente por sí sola:
- La red es confiable;
- La latencia es cero;
- El ancho de banda es infinito;
- La red es segura;
- La topología nunca cambia;
- Hay un solo administrador;
- El costo de transporte es cero;
- La red es homogénea.
Estas falacias nos recuerdan que cada llamada entre servicios puede fallar, que el tiempo de respuesta puede variar, que la red puede sufrir interrupciones, que las dependencias externas pueden no estar disponibles, y que todo eso debe preverse si queremos que nuestra aplicación sea realmente resiliente.
Sin embargo, las falacias se centran solo en la comunicación por red. Aunque se implementen mecanismos para esos puntos de riesgo, la resiliencia todavía no se alcanzará como característica general de la arquitectura.
¿Resiliente a qué?
La resiliencia no se reduce a un único punto de control, y eso es lo que hace que nada sea 100% resiliente. La resiliencia no depende solo de factores no funcionales, sino principalmente de factores funcionales de la aplicación, lo que hace que esta característica sea relativa a lo que cada software se propone resolver.
Para distintos servicios, la resiliencia se presenta de formas diferentes, como en los ejemplos de abajo, en los que cada escenario tiene una necesidad distinta:
| Escenario | Necesidad de resiliencia |
|---|---|
| Requisito de negocio: portal de noticias | Los contenidos deben estar siempre actualizados y nunca dejar de entregarse. |
| Servicio de autenticación | Garantizar la autenticación de los usuarios aunque el servicio de autenticación esté caído. |
| Cambios de arquitectura | Garantizar que los cambios puedan ocurrir sin afectar a los clientes del servicio. |
| Seguridad | El sistema debe mitigar los intentos de ataque de forma ágil y mantenerse estable para los demás usuarios. |
Conclusión
Al final, podemos volver a preguntar: ¿la arquitectura de microservicios, por sí sola, es resiliente? Puedo afirmarlo sin dudas: definitivamente no.
Claro que la arquitectura de microservicios ofrece posibilidades más prometedoras para implementar resiliencia que otros estilos arquitectónicos. Pero la resiliencia no es un flag que se marca como verdadero en la aplicación, ni se reduce a agregar una herramienta que trate un único punto de falla. Es una característica mucho más compleja, amplia y profunda de lo que parecían sugerir las afirmaciones iniciales.
Como consejo, diría: investiga tu sistema y entiende el dominio para encontrar sus puntos de control, ordénalos por prioridad y resuélvelos a medida que sea posible. Y nunca dejes de revisar esos puntos de control para verificar que cumplen lo esperado en relación con sus responsabilidades.
Recuerda: la arquitectura de software está hecha de decisiones y trade-offs, no de promesas listas.
Este es un tema amplio y lleno de matices. Si tienes vivencias, aprendizajes o desacuerdos, cuéntame. Aprendamos unos de otros y enriquezcamos la discusión sobre arquitectura y resiliencia.