Capítulo 1. La reactividad en pocas palabras
Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com
Reactivo es una palabra sobrecargada. Es posible que hayas buscado reactivo con un buscador para entender de qué se trata. Si no lo has hecho, no te preocupes: te has ahorrado mucha confusión. Hay muchos reactivos: Sistemas Reactivos, Programación Reactiva, Extensiones Reactivas, Mensajería Reactiva... Cada día aparecen nuevas. ¿Son todas estas "reactivas" la misma reactiva? ¿Son diferentes?
Éstas son las preguntas a las que vamos a responder en este capítulo. Vamos a echar un vistazo al panorama reactivo para identificar y ayudarte a comprender los distintos matices de reactivo, lo que significan, los conceptos asociados a ellos y cómo se relacionan entre sí. Porque sí, sin estropear demasiado, todos estos "reactivos" están relacionados.
Nota
Como se indica en el prefacio, utilizamos el sustantivo Reactivo, con R mayúscula, para agrupar todas las diversas facetas del panorama reactivo, como la programación reactiva, los sistemas reactivos, los flujos reactivos, etc.
¿Qué entendemos por reactivo?
Empecemos por el principio. Olvídate por unos minutos del software y la informática, y utiliza un enfoque a la antigua usanza. Si buscamos reactivo en el Diccionario Oxford de Inglés, encontramos la siguiente definición:
reactivo(adjetivo)
Que muestra una respuesta a un estímulo. 1.1 Que actúa en respuesta a una situación en lugar de crearla o controlarla. 1.2 Que tiene tendencia a reaccionar químicamente. 1.3 (Fisiología) Que muestra una respuesta inmunitaria a un antígeno específico. 1.4 (De una enfermedad o dolencia) Causada por una reacción a algo. 1.5 (Física) Relativa a la reactancia.
Entre estas definiciones, dos son relevantes en nuestro contexto. La primera definición, mostrar una respuesta a un estímulo, se refiere a algún tipo de reacción. Ser reactivo significa reaccionar ante estímulos, sean cuales sean. La subdefinición 1.1 dice que ser reactivo también consiste en enfrentarse a situaciones inesperadas e incontroladas. Verás a lo largo de este libro que las aplicaciones nativas de la nube, y los sistemas distribuidos en general, se enfrentan a muchas situaciones de este tipo. Aunque estas definiciones son interesantes, no se aplican al software.Pero podemos tener en cuenta estas definiciones para elaborar una nueva específica del software:
1.6 (Software) Una aplicación que reacciona a estímulos, como eventos, peticiones y fallos del usuario.
Sin embargo, como verás en este libro, la reactividad actual va más allá. La reactividad es un enfoque para diseñar, implementar y razonar sobre tu sistema en términos de eventos y flujos. Reactivo es construir aplicaciones elásticas, resistentes y con capacidad de respuesta. Reactivo es también utilizar los recursos mediante una gestión eficiente de los recursos y la comunicación. Dicho de otro modo: Reactivo es diseñar y construir mejores sistemas distribuidos, más robustos y eficientes. Los llamamos sistemas reactivos.
El software reactivo no es nuevo
Pero espera, la definición (1.6) que acabamos de dar no es innovadora. Al contrario, puede que sientas cierto déjà vu, ¿no? ¿No es la naturaleza del software reaccionar a las entradas del usuario y a las señales del sistema operativo? ¿Cómo se comporta el software cuando pulsas una tecla? Reacciona. Entonces, ¿por qué hay tantos libros, charlas y debates sobre la Reactividad si se trata simplemente de software normal?1 Por favor, ten paciencia; hay algo más.
Pero tienes razón; lo reactivo no es nuevo, en realidad es bastante antiguo. Podemos rastrear la base de las ideas que subyacen al software reactivo hasta justo después de la aparición de los ordenadores en los años 50. El DYSEAC, un ordenador de primera generación (en funcionamiento en 1954), ya utilizaba interrupciones de hardware como optimización, eliminando el tiempo de espera en los bucles de sondeo. Este ordenador fue uno de los primeros sistemas en utilizar la arquitectura reactiva y dirigida por eventos!
Reaccionar ante los acontecimientos implica estar orientado a los acontecimientos.El software orientado a los acontecimientos recibe y produce acontecimientos. Los acontecimientos recibidos determinan el flujo del programa.Un aspecto fundamental de estar orientado a los acontecimientos es la asincronía: no sabes cuándo vas a recibir acontecimientos.2 Ésa es precisamente la definición 1.1 de la sección anterior. No puedes planificar cuándo vas a recibir eventos, no controlas qué eventos vas a recibir y tienes que estar preparado para manejarlos. Ésa es la esencia de ser reactivo: ser asíncrono.
El paisaje reactivo
A partir de esta idea de ser asíncrono y dirigido por eventos, han surgido muchas formas de Reactividad. El paisaje reactivo es amplio y abarrotado. La Figura 1-1 muestra un extracto de este paisaje y las relaciones entre los principales reactivos.
Pero no olvides nuestro objetivo: construir mejores sistemas distribuidos -sistemas reactivos-. Los otros "reactivos" están aquí para ayudarnos a implantar estos sistemas.
Las razones de Reactivo, y de los sistemas reactivos en particular, provienen de los sistemas distribuidos. Como verás en el Capítulo 3, construir sistemas distribuidos es difícil.En 2013, expertos en sistemas distribuidos escribieron la primera versión de "El Manifiesto Reactivo" e introdujeron el concepto de sistemas reactivos.
Sí, puedes construir sistemas distribuidos sin aplicar los principios reactivos. La reactividad proporciona un modelo para garantizar que no se han pasado por alto problemas conocidos significativos durante la arquitectura y el desarrollo de tu sistema. Por otra parte, puedes aplicar estos principios en sistemas no distribuidos.
Un sistema reactivo es, ante todo, receptivo. Debe atender las peticiones a tiempo, incluso bajo carga o cuando se enfrenta a fallos. Para lograr esta capacidad de respuesta, el manifiesto propone utilizar el paso asíncrono de mensajes como forma principal de comunicación entre los componentes que forman el sistema. En el Capítulo 4 verás cómo este método de comunicación permite la elasticidad y la resiliencia, dos atributos esenciales de los sistemas distribuidos sólidos. El objetivo de este libro es mostrarte cómo construir sistemas reactivos de este tipo con Quarkus. Así pues, construir sistemas reactivos es nuestro objetivo principal.
Infundir el paso de mensajes asíncronos en el núcleo de los sistemas distribuidos no viene sin consecuencias. Tu aplicación necesita utilizar código asíncrono y E/S no bloqueantes, la capacidad que proporciona el sistema operativo de poner en cola las interacciones de E/S sin tener que esperar activamente a que se completen. (Tratamos las E/S no bloqueantes en el Capítulo 4). Esto último es esencial para mejorar la utilización de los recursos, como la CPU y la memoria, otro aspecto importante de la Reactividad. Hoy en día, muchos conjuntos de herramientas y marcos de trabajo, como Quarkus, Eclipse Vert.x, Micronaut, Helidon y Netty, utilizan E/S no bloqueantes por esta misma razón: hacer más con recursos limitados.
Sin embargo, tener un tiempo de ejecución que aproveche la E/S no bloqueante no es suficiente para ser reactivo. También necesitas escribir código asíncrono que adopte la mecánica de E/S no bloqueante. De lo contrario, los beneficios de la utilización de recursos se desvanecerían. Escribir código asíncrono es un cambio de paradigma. Del tradicional (imperativo), do x; do y;
, ahora vas a configurar tu código como on event(e) do x; on event(f) do y;
.
En otras palabras, para ser reactivo, no sólo tu sistema es una arquitectura orientada a eventos, sino que también tu código va a pasar a estar orientado a eventos.Uno de los enfoques más sencillos para implementar dicho código son las retrollamadas: registras funciones invocadas cuando se reciben eventos. Como los futuros, las promesas y las coroutinas, todos los demás enfoques se basan en retrollamadas y ofrecen API de nivel superior.
Nota
Tal vez te preguntes por qué las hojas de cálculo están en el paisaje. Las hojas de cálculo son reactivas. Cuando escribes una fórmula en una celda y cambias un valor leído (en otra celda) por la fórmula, se actualiza el resultado de esta fórmula. La celda reacciona a la actualización de un valor (evento), y el resultado (reacción) es el nuevo resultado. Sí, ¡puede que tu jefe sea mejor desarrollador reactivo que tú! Pero no te preocupes, este libro cambiará esto.
La programación reactiva, tratada en el Capítulo 5, también es un enfoque para escribir código asíncrono. Utiliza flujos de datos para estructurar tu código. Observas los datos que transitan en estos flujos y reaccionas ante ellos. La programación reactiva proporciona una potente abstracción y API para dar forma al código orientado a eventos.
Pero utilizar flujos de datos conlleva un problema. Si tienes un productor rápido conectado directamente a un consumidor lento, puedes inundar al consumidor. Como verás, podemos usar buffers o un corredor de mensajes entre medias, pero imagina inundar a un consumidor sin ellos. Eso iría en contra de las ideas de capacidad de respuesta y antifragilidad promovidas por Reactive. Para ayudarnos con ese problema concreto, Reactive Streams propone un protocolo de contrapresión asíncrono y no bloqueante en el que el consumidor señala al productor su disponibilidad. Como puedes imaginar, esto puede no ser aplicable en todas partes, ya que algunas fuentes de datos no pueden ralentizarse.
La popularidad de los Streams Reactivos ha aumentado en los últimos años. Por ejemplo, RSocket es un protocolo de red basado en Reactive Streams. R2DBC propone el acceso asíncrono a bases de datos mediante Reactive Streams. Además, RxJava, Project Reactor y SmallRye Mutiny adoptaron los flujos reactivos para gestionar la contrapresión. Por último, Vert.x permite mapear el modelo de contrapresión de Vert.x a Reactive Streams.3
Así concluye nuestro rápido recorrido por el panorama reactivo. Como hemos dicho, está abarrotado de muchos términos y muchas herramientas. Pero nunca pierdas de vista el objetivo general de Reactivo: construir mejores sistemas distribuidos. Ése es el objetivo principal de este libro.
¿Por qué las arquitecturas reactivas son tan adecuadas para las aplicaciones nativas de la nube?
La nube -pública, privada o híbrida- ha puesto a Reactive en el punto de mira. La nube es un sistema distribuido. Cuando ejecutas tu aplicación en la nube, esa aplicación se enfrenta a un alto grado de incertidumbre. El aprovisionamiento de tu aplicación puede ser lento, o rápido, o incluso fallar. Las interrupciones de comunicación son habituales, debido a fallos de red o particiones. Puedes encontrarte con restricciones de cuota, escasez de recursos y fallos dehardware. Algunos servicios que utilizas pueden no estar disponibles en algunos momentos o ser trasladados a otras ubicaciones.
Aunque la nube proporciona unas facilidades extraordinarias para la capa de infraestructura, sólo cubre la mitad de la historia. La segunda mitad es tu aplicación, que tiene que diseñarse para formar parte de un sistema distribuido y comprender los retos que supone formar parte de un sistema de este tipo.
Los principios reactivos que cubrimos en este libro ayudan a aceptar la incertidumbre y los retos inherentes a los sistemas distribuidos y las aplicaciones en la nube. No los oculta, al contrario, los abraza.
A medida que los microservicios y la informática sin servidor se convierten en estilos arquitectónicos prominentes, los principios reactivos cobran aún más importancia, ya que pueden ayudarte a garantizar que diseñas tu sistema sobre una base sólida.
La reactividad no es una bala de plata
Como todo, la Reactividad tiene pros y contras. No es un arma mágica. Ninguna solución funciona en todas partes.
¿Recuerdas los microservicios a finales de la década de 2010? Rápidamente se hicieron muy populares, y muchas organizaciones los implementaron en áreas para las que quizá no eran adecuados, lo que a menudo cambiaba un conjunto de problemas por otro. Al igual que las arquitecturas de microservicios, las arquitecturas reactivas tienen áreas en las que son adecuadas, y brillan en aplicaciones distribuidas y en la nube, pero pueden ser desastrosas en sistemas más monolíticos y centrados en la computación. Brillan en las aplicaciones distribuidas y en la nube, pero pueden ser desastrosas en sistemas más monolíticos y centrados en la computación. Si tu sistema depende de la comunicación remota, el procesamiento de eventos o la alta eficiencia, la Reactividad será interesante. Si tu sistema utiliza principalmente interacciones en proceso, gestiona sólo unas pocas peticiones al día o es intensivo en computación, entonces la Reactividad no aportará nada más que complejidad.
Con la Reactividad, pones la noción de eventos en el centro de tu sistema. Si estás acostumbrado a la forma tradicional síncrona e imperativa de construir aplicaciones, el camino para convertirte en reactivo puede ser empinado. La necesidad de volverse asíncrono trastorna la mayoría de los marcos de trabajo tradicionales. Nos estamos alejando de la conocida Llamada a Procedimiento Remoto (RPC) y de los puntos finales HTTP. Así que, con ese descargo de responsabilidad, ¡es hora de iniciar nuestro viaje!
1 Puedes encontrar multitud de charlas sobre Reactiva en YouTube.
2 Asíncrono es lo contrario de síncrono. Ser asíncrono significa suceder en un momento diferente, mientras que ser síncrono significa suceder al mismo tiempo.
3 Para más detalles, consulta Integración Vert.x Reactive Streams.
Get Sistemas reactivos en Java now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.