Pasar al contenido principal
Cargando...

Spring WebFlux

Inspiring technology by Hunters

Hoy nuestros Hunters nos hablan de Spring WebFlux, el framework MVC que forma parte de la nueva release de Spring framework 5.X para aplicaciones desarrolladas bajo un paradigma Reactive

Las aplicaciones reactivas son aplicaciones no bloqueantes, cuyas hebras que atienden peticiones nunca se quedan esperando a que se resuelvan operaciones de entrada/salida: llamada a un servicio externo, consulta a una base de datos, acceder a un fichero del sistema de archivos... Por el contrario, la petición se atiende, se registra un Callback a ejecutar cuando el recurso solicitado se resuelve y, enseguida, la hebra pasa a otra operación. De esta manera se minimizan las esperas, pero también los recursos de CPU y memoria, ya que hacen falta menos hebras para atender las peticiones. Por tanto, una aplicación reactiva escala mejor que una aplicación imperativa.

¿Cuál es la arquitectura de Spring WebFlux?

Spring MCV

Las aplicaciones MVC Imperativas funcionan bajo la especificación Servlet hasta su versión 3.0 y están basadas en un modelo Thread Pool: cada petición es atendida por una hebra creada al efecto.

Cada hebra que atiende la petición queda bloqueada mientras resuelve operaciones de entrada/salida, tales como consultar una base de datos. Además, cualquier información que la hebra pueda necesitar (contexto de seguridad, estado de la transacción de base de datos…) se guarda en la estructura ThreadLocal.

Servlet Dispatcher

Figura 1: Servlet Dispatcher.

La arquitectura MVC clásica usa un modelo de hebras llamado Thread Per Request:

Thread Per Request

Figura 2: Thread Per Request.

En este caso, una hebra atenderá la petición y si hay algún bloqueo, tal como una petición a base de datos o acceso a un sistema de archivos remoto, esta quedará bloqueada hasta que el recurso esté disponible.

Spring WebFlux

Las aplicaciones desarrolladas bajo Spring WebFlux son aplicaciones que siguen un paradigma Funcional Reactivo. La programación reactiva es un paradigma declarativo funcional que se basa en flujos de datos asíncronos y la propagación del cambio.

Como las peticiones van a ser tratadas por varias hebras, Spring WebFlux no utiliza ThreadLocal, al carecer de sentido y ser muy costoso. El sustituto de ThreadLocal son los Context.

En cuanto al manejo de las peticiones, el ServletDispatcher es sustituido por DispatcherHandle. En el caso de los los filtros servlets, estos son sustituidos por WebFilters.

Adicionalmente, Spring WebFlux incorpora el proyecto Reactor (soporta también RxJava) como motor reactivo. Reactor requiere de Java 8 para poder funcionar.

Rest Controller

Figura 3: Servlet Dispatcher.

El modelo de hebras que utiliza Spring WebFlux se llama Event Loop y funciona de la siguiente manera:

Event Loop

Figura 4: Event Loop.

En este modelo hay un bucle de eventos por cada core lógico de la CPU. La idea es que cada petición se convierte en un evento, que se procesa de manera secuencial. El procesado consiste en registrar un callback y retornar inmediatamente. Cuando la operación de entrada/salida se completa se ejecuta el callback, cuya respuesta es lanzada al invocador original. Este modelo es implementado en servidores como Netty, Node.js o Nginx.

MVC vs WebFlux

Los sistemas basados en WebFlux escalan mucho mejor y respetan los tiempos de respuesta, al manejar mejor la carga de trabajo. Para demostrar esto se ha hecho una prueba sencilla:

Se crean dos versiones de servicio Rest, que recuperan 1300 registros de una base de datos en memoria H2 sin ningún tipo de filtro u ordenación. Los parámetros de las pruebas son:

  • Una CPU con 8 cores lógicos y una frecuencia de 2.42 GHz.
  • Una memoria ram de 32 GB a 3200 MHz.
  • 500 usuarios concurrentes atacando los servicios Rest para obtener todos los registros (findAll).
  • 0 iteraciones. En total, 5000 peticiones atendidas.
Imperative vs Reactive

Figura 5: Imperative vs Reactive.

Las métricas obtenidas son:

ImperativeServiceApplication (izquierda):

  • Picos de memoria de 415 Mb.
  • Más de 100 Hebras creadas.
  • Picos de CPU que superan el 50% de la capacidad.
  • 13.065 clases cargadas.

ReactiveServiceApplication (derecha):

  • Picos de memoria de 310 Mb.
  • Menos de 40 Hebras creadas.
  • Picos de CPU inferiores al 15% de la capacidad.
  • 10.847 clases cargadas.

Estas métricas permiten a los sistemas reactivos soportar mas carga que los imperativos

Principales conclusiones del uso de Spring Webflux

  • Spring WebFlux presenta mejores parámetros de rendimiento, siempre que las Entrada/Salidas de datos tengan cierta latencia.  
  • Reactive programming tiene una curva de aprendizaje que asumir, ya que implica un cambio de paradigma.
  • Pueden usarse conjuntamente Spring WebFlux y Spring MVC aunque se pierde buena parte de la capacidad de Webflux, por lo que se debería apostar por un enfoque 100% reactivo.

Dado que WebFlux requiere de operaciones de Entrada/Salida no bloqueantes, aún hay mucho trabajo por hacer, ya que no todos los drivers de las bases de datos relacionales están adaptados a este paradigma. 

WebFlux también rompe con la especificación servlet clásica (soporta especificación servlet 3.1+) por lo que módulos como Spring Security se ven afectados y se requieren de configuraciones distintas dependiendo si se usa un enfoque imperativo o reactivo.

En resumen: WebFlux es una buena apuesta para la implementación de sistemas resilientes, elásticos y tolerante a fallos pero requiere empezar un poco de nuevo a nivel tecnológico, pues aunque sigue siendo Java y Spring, la manera de hacer las cosas han cambiado.

¿Quieres saber más sobre Hunters?

En Altia hemos diseñado varios programas para que las personas que estén terminando su carrera o sean recién tituladas puedan iniciarse en el sector IT, sumando su talento y pasión por la tecnología. Uno de ellos es Hunters: personas que les gustan las tendencias, tienen alma innovadora y contribuyen a anticipar los retos del futuro.

Formar parte de Hunters es formar parte de un grupo transversal con capacidad de generar y transferir conocimiento

LinkedIn José Luis Antón Bueso

José Luis Antón Bueso

Solution Architect en Altia