featured image

En cada una de mis charlas sobre Erlang siempre comienzo explicando el cambio sucedido hace bastantes años de programación secuencial a programación paralela y concurrente. Un cambio que significó repensar el software de otra forma. Un grupo de programadores escribió el Manifiesto de Sistemas Reactivos para indicar pautas a seguir, ¿aún no lo has firmado?

El Manifiesto Reactivo es un documento (un manifiesto) que recoge una serie de intenciones e ideas a seguir para hacer sistemas reactivos, pero…

¿Qué son los Sistemas Reactivos?

Los Sistemas Reactivos son sistemas: responsivos, resilientes, elásticos y orientados a mensajes. Todos estos conceptos rimbombantes no son autoexplicativos por sus nombres. Quizás ya sepas qué significa alguno de ellos. Vamos a profundizar en cada uno:

Sistemas Responsivos

Los sistemas responsivos son sistemas que responden de una forma oportuna y en la medida de lo posible. Estos sistemas se orientan en obtener tiempos de respuesta rápidos (milisegundos), consistentes y efectivos.

La idea es desarrollar servicios de respuesta rápida y tener siempre presente el rendimiento. Esto se debe a un decremento en la velocidad experimentado en general por avances que han hecho bajar la velocidad de los sistemas, incluso cuando la capacidad y rendimiento del hardware se ha incrementado enormemente.

Por ejemplo cuando hablaba en este artículo sobre Yaws señalaba su capacidad para obtener siempre una respuesta incluso en momentos de mucha carga. Ninguna petición quedaba sin respuesta.

Sistemas Resilientes

Los sistemas resilientes permanecen responsivos ante fallos. Son sistemas que disponen de alta disponibilidad, sistemas de misión crítica. La resilencia es necesaria para cualquier sistema responsivo. Estos sistemas se consiguen a través de replicación, contención, aislamiento y delegación.

Su definición podría ajustarse a la capacidad de un sistema de recuperarse ante los errores. De nuevo, como decía en otro artículo sobre Erlang e incluso señalo en el libro Erlang/OTP Volumen I: Un Mundo Concurrente, en el extracto del primer capítulo, los sistemas Erlang/OTP están diseñados con tolerancia a fallos. Esto quiere decir que un error afecta solo al proceso o a la petición pudiendo recuperarse de algún modo seguro y por supuesto sin afectar al resto del sistema, otras peticiones y funcionamiento en general.

Sistemas Elásticos

Los sistemas elásticos se mantienen responsivos independientemente del nivel de carga. El número de elementos del sistema puede variar ampliándose o disminuyéndose para atender más o menos demanda y ante estos cambios el sistema debe seguir siendo responsivo y resiliente.

En la actualidad sistemas como Kubernetes o Docker Swarm en el terreno de los contenedores o incluso Amazon Web Services o DigitalOcean en el terreno de los servidores virtuales nos permiten de alguna forma dimensionar nuestros sistemas. Ambos de una forma u otra permiten crear plantillas, imágenes o fotografías del sistema y levantar otros similares para atender más carga. Igualmente nos permiten eliminar estos nuevos elementos de la red cuando los momentos de carga han pasado ajustando el presupuesto a la necesidad de nuestro negocio.

Sistemas Orientados a Mensajes

Los sistemas orientados a mensajes asíncronos permiten la gestión aún más rápida de tareas sin bloqueos. Estos sistemas mantienen un bajo nivel de acoplamiento, aislamiento y proporcionan medios para delegar la gestión de errores.

En la actualidad hay muchas tareas que se realizan en nuestro sistema y se pueden realizar en segundo plano. Gracias a conexiones websockets incluso podemos mantener informado al usuario a través del envío de información periódica sobre el estado de la tarea al navegador. Tareas como el envío de mensajes de correo masivos para clientes, anotar información estadística sobre el uso de nuestro sistema, o incluso mantener un flujo de eventos constante desde nuestra aplicación hacia un sistema de mensajería como RabbitMQ o un sistema de flujo de información como Apache Kafka nos facilita la tarea enormemente.

Micro servicios

Aunque el manifiesto no habla específicamente de ellos, al decir que los grandes sistemas estarán compuestos de otros más pequeños con las mismas características ya dejan entrever la constitución de un sistema a través de pequeños elementos o unidades que se mantengan aislados y operantes, responsivos, resilientes y elásticos de forma individual para conseguir un sistema como un conjunto igualmente responsivo, resiliente y elástico e igualmente orientado a mensajes asíncronos en toda su interacción.

De este modo no es de extrañar que al construir nuestros sistemas empleando sistemas de mensajes como RabbitMQ necesitemos consumidores separados del sistema principal encargados de ir leyendo los mensajes y produciendo nueva información, nuevos eventos e incluso nuevos mensajes en nuevas colas para otros elementos del sistema. En muchos casos, además del protocolo web HTTP también se emplean otros como AMQP, MQTT o incluso en algunos casos XMPP.

Por otro lado ya no solo vemos servicios basados en HTTP REST sino también se comienza a ver más GraphQL para simplificar y dar más versatilidad a la toma de datos de unos (micro)servicios a otros.

Sistemas y Lenguajes

Estos nuevos requisitos son posibles de desarrollar en los lenguajes más empleados a día de hoy como Java, PHP, Ruby o Python entre otros, pero siempre tendremos la tentación de obviar algunas partes y caer en la tentación de sucumbir a la simpleza de los sistemas monolíticos denegando en algún punto la capacidad de ser resilientes o elásticos.

Por ejemplo, el creador de Node.js creó su sistema basado en un lenguaje que no tenía difusión en desarrollo a nivel de servidor para forzar el uso de librerías completamente nuevas y permitirle así crear sistemas no bloqueantes.

En este sentido lenguajes como Rust, Go, Erlang, Elixir, Crystal o Pony entre otros han sido concebidos con todas estas directivas y hacen posible y más fácil la creación de sistemas con estas propiedades.

Conclusiones

Los sistemas reactivos son los sistemas que cada vez más se necesitan en la base de operaciones de startups y empresas orientadas a la nube. Empresas que desarrollen un producto o servicio a través de Internet y necesitan escalar, crecer y no centrarse en solventar límites impuestos por viejos lenguajes o infraestructuras.

¿Has desarrollado algún sistema reactivo?, ¿has encontrado problemas que se resolverían empleando las características descritas?, ¿Te has lanzado a alguna plataforma o lenguaje que proporcione la creación más fácil de sistemas reactivos? ¿Necesitas ayuda en portar o crear sistemas reactivos? ¡Déjanos un comentario!