概述
Spring web 提供了两条技术方案:
springMVC(servlet): 基于线程,阻塞IO
WebFlux(Reactive): 多路复用非阻塞IO
spring mvc | web flux | |
Programming Model | Synchronous, blocking | Asynchronous, non-blocking |
I/O Model | Blocking I/O | Non-blocking I/O |
Concurrency Handling | Thread-per-request | Event-loop, few threads |
Reactive Support | Limited | Full reactive support |
Framework Base | Servlet API | Reactive Streams API, Project Reactor |
Ideal Use Cases | Traditional web applications | Real-time, high-concurrency applications |
注意事项 | 推荐使用,整个技术栈成熟, 比如jdbc等组件都是技术线程的 | 谨慎使用,理论先进,性能好,但生态不成熟, 无法使用基于线程的其他组件,比如jdbc jdbc的替代方案是R2DBC ;可以在纯web场景使用, spring gateway |
Reactive
Reactive systems have certain characteristics that make them ideal for low-latency, high-throughput workloads. Project Reactor and the Spring portfolio work together to enable developers to build enterprise-grade reactive systems that are responsive, resilient, elastic, and message-driven.
What is reactive processing?
Reactive processing is a paradigm that enables developers build non-blocking, asynchronous applications that can handle back-pressure (flow control).
Why use reactive processing?
Reactive systems better utilize modern processors. Also, the inclusion of back-pressure in reactive programming ensures better resilience between decoupled components.
Springboot 的两条技术栈:
In the context of a Spring application, a stack is a resource package that determines the specific architecture, framework, etc. that an application requires. The Spring Framework has two different stacks:
Servlet Stack
This is a classic! It was created by Spring and is the most commonly used by developers around the world. It supports some Servlet Containers such as Tomcat, Jetty, and Undertown. For this stack, we develop our code with the Spring MVC Framework.
Synchronous and asynchronous calls can be used, but with the blocking/IO architecture. For every request, the user must wait for a response before proceeding. This model works over a thread pool, which is always incremented when there is a huge API call traffic. Consequently, you will have high hardware consumption when there is a large number of requests.
Reactive Stack
After some years, the Spring Framework 5 released the Reactive Stack. The objective of this stack was to allow the Spring applications to have a higher performance during huge traffic data and large concurrency. But how does it do this? The Reactive Stack possesses new features such as non-blocking/IO architecture, Servlet Container 3.1, Netty Server, Spring WebFlux Framework, etc. It operates on a ‘less is more’ principle, as it can attend to large concurrency utilizing fewer hardware resources.
Reactive vs Servlet Stack
Let’s reiterate that the purpose of these stacks is not to eliminate the other but to attend to specific needs.
- Learning Path
The Servlet Stack caters to what developers are accustomed to developing presently, which is imperative code. It is easy to write, read and debug. In constrast, the Reactive Stack uses funcional programming, which requires a deeper understanding and the implementation of a more complex code.
- Execution Model
There are two different execution models: The Reactive Stack applies an Event Loop, similar to NodeJS. It has the capacity to handle many requests from the client with only a few threads. All requests are processed in an event queue. When a new request is received, the thread is released and a callback is always registered. For the Servlet stack, however, we implement the Thread per Request Model to handle requests. This model works over a thread pool, blocking each incoming request on the Servlet API. Once the thread’s number runs out, we must wait until one of them is released. There is a significant amount of hardware resource consumption with this model.
- Non-Blocking/IO vs Blocking/IO
The Blocking/IO is an architecture type utilized on the Servlet API. Although we are able to execute asynchronous operations with Spring MVC, it is limited when a request arrives at the Servlet API because the server will block all completed remote calls. The Reactive Stack brought the Servlet API 3.1 and the Netty Server, which both support Non-Blocking/IO processes, removing the need for the final user to wait for a response.
相关名词解释-backpressure
Backpressure is a concept in reactive programming and stream processing that deals with the problem of handling a situation where the data producer is generating data faster than the consumer can process it. When this happens, the system needs a way to manage the flow of data to avoid overwhelming the consumer and potentially causing system failures or degraded performance.
Key Concepts of Backpressure
- Producer: The source of the data stream. It could be a server sending data over a network, a user interface generating events, or any other source of data.
- Consumer: The entity that processes or consumes the data. This could be a function, a service, or another system component.
- Buffering: Temporarily storing data when the consumer cannot keep up with the producer. This is a short-term solution as buffers have limited capacity.
- Throttling: Limiting the rate at which the producer sends data to the consumer to prevent overload.
- Dropping: Discarding some data when the buffer is full to prevent overflow.