Reactive Programming- Spring WebFlux
For web development, we used the Dispatcher Servlet as a gateway that maps the requests to the handlers. And it uses the servlet API and containers which means that for each of our requests the resource is blocked. That’s why we need a bigger thread pool and more resources for our web projects. And we are also faced with scaling problems. According to Reactive Manifesto, reactive systems are Responsive, Resilient, Elastic, and Message-driven. Reactive programming provides an asynchronous, non-blocking, event-driven approach to data processing. Reactive code is fully declarative and it uses a subscriber to attach a publisher. That’s why we prefer reactive applications for writing microservices applications. Spring-MVC is based on thread pools, on the other hand, Spring-WebFlux is based on event-driven mechanisms.
With Spring 5, WebFlux support is added. It is async and non-blocking. Spring WebFlux is the reactive alternative to Spring MVC. Spring WebFlux supports servlet containers such as Tomcat or Jetty. And applications can be deployed on Servlet 3.1. It also supports non-servlet runtimes such as Netty and Undertow. While developing reactive applications, we have to be sure about all the components are reactive, otherwise, there is a risk of blocking. That’s why we don’t want to use relational databases, instead, we use NoSQL which provides reactive access.
eactive Programming is an implementation technique to ensure that the individual services use an asynchronous, non-blocking model. The main benefit of non-blocking IO is that we need fewer threads to handle the same amount of IO requests A thread costs around 1MB. Spring WebFlux is an annotation-based web framework built on Project Reactor and provides two main types called Flux and Mono.
Flux and Mono are the Publisher implementations of Spring WebFlux:
With Mono, it only returns 0 or 1 single value. Flux returns 0 or N items.
Mono<String> greeting = Mono.just(“Hello”);
Mono<String> greeting = Mono.empty();
Flux<String> cars= Flux.just(“Mercedes”, “BMW”, ”Porsche”);
Spring WebFlux runs on servers such as Netty, Undertow, and Servlet 3.1+ containers. Netty is the default server in a WebFlux application. Netty uses the event loop model to provide highly scalable concurrency in a reactive asynchronous manner. EventLoopGroup manages one or more EventLoop which must be continuously running. The event loop runs continuously in a single thread, although we can have as many event loops as the number of available cores.
When netty is compared with tomcat, netty uses an event loop mechanism and uses fewer threads while Apache Tomcat still uses a model of one thread per request. So the number of threads used is, higher in numbers.
WebClient is the reactive HTTP client that is part of Spring WebFlux.WebClient also implements concurrency using the event loop model. WebClient also shares the event loop that Netty uses for the server.
Spring Webflux has performance advantages, on the other hand, It may bring complexity to the project and team, and debugging issues may take some time if you are not experienced enough. It may be convenient to use partially where you have performance and latency issues.
I have created a sample WebFlux project using spring-boot, located on GitHub.The sample project uses the Netty and Mono & Flux implementations.