Webflux



Table of Contents

Spring Web Reactive Module

Modern applications can reach huge numbers of simultaneous users, and although modern hardware capabilities have continued to improve, modern software performance is still a key concern.

The Spring Framework 5 allows internal use of Reactor for its reactive support. Reactor is a Reactive Streams implementation that further expands the simple Reactive Streams Publisher contract with the Flux and Mono composable API forms to include the 0..N and 0..1 data sequence declarative operations.

Spring Framework 5 adds a new spring-web-reactive module supporting the same @Controller programming model as Spring MVC but running on a non-blocking, reactive engine. The diagram below shows how, side by side, Spring MVC and Spring Web Reactive compare:

Using WebFlux

Spring MVC or WebFlux

Spring MVC and WebFlux can work together to expand the variety of options available. The two are designed to ensure continuity and integrity. The diagram below illustrates how the two interact, what they have in common and what each supports in a particular way.

Servers

Spring WebFlux is supported on Servlet runtimes such as Tomcat, Jetty (Servlet 3.1+) and on non-Servlet runtimes such as Netty and Undertow. All servers are adapted to a common low level API in order to support higher level programming models across servers.

Spring Boot is equipped with a WebFlux start that automates the usage of WebFlux. By default, the starter uses Netty, but changing your Maven or Gradle dependencies makes it easy to switch to Tomcat, Jetty or Undertow. Spring Boot defaults to Netty as it is used more widely in asynchronous, non-blocking space and allows the sharing of resources between a client and a server.

Tomcat and Jetty are suitable for use with both Spring MVC and WebFlux. Nevertheless bear in mind that the way they are used is very different. Spring MVC relies on I / O blocking by Servlet and allows applications to directly use the Servlet API if they need to. Spring WebFlux relies on non-blocking I/O services from Servlet 3.1 and uses the Servlet API behind a low-level adapter. It is not directly exposed to use.

Performance

In general, reactive and non-blocking doesn't make programs run faster. In certain cases (for example, if the WebClient is used to run remote calls in parallel) they can. All in all, doing it the non-blocking way requires more effort, and this can slightly increase the processing time needed.

Reactive and non-blocking's main advantage is the ability to scale with a low, fixed number of threads and less memory. That makes applications under load more robust, since they scale more predictably. However, you need to have some latency (including a combination of sluggish and volatile I/O network) to achieve such benefits. This is where the reactive stack continues to show its abilities, and the variations can be dram

Concurrency

Both the Spring MVC and Spring WebFlux support annotated controllers but there is a major gap in the concurrency model.

roughly speaking in blocking servers (e.g. servlet-based applications), it is assumed that applications can block the current thread (for remote calls, for example). For this reason, servlet containers use a large thread pool during request handling to absorb potential blockages. and in non-blocking servers, applications are presumed not to block. Non-blocking servers therefore use a small, fixed-size thread pool (event-loop workers) to handle requests.

Reactive Core

The spring-web module provides the following basic support for reactive Web applications:

Server side

For server request processing there are two levels of support.

HttpHandler

Basic contract for HTTP request handling with non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty, Undertow, Tomcat, Jetty, and any Servlet 3.1+ container.

WebHandler API

Slightly higher level, general-purpose web API for request handling, plus concrete programming models such as annotated controllers and functional endpoints.

Client side

On the client side, there is a simple contract on executing HTTP requests with non-blocking back pressure I/O and Reactive Streams, along with adapters for Reactor Netty and the reactive Jetty HttpClient. The higher level WebClient used in applications builds on this basic contract.

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-framework-choice

https://blog.knoldus.com/spring-reactive-programming-in-java/

https://allegro.tech/2019/07/migrating-microservice-to-spring-webflux.html



The example of this tutorial can be seen here: Spring Examples - WebFlux

image © spring.io