Reactive Programming in Java-Reactive Streams JVM
Reactive specification is the JVM Reactive extension specification Reactive Streams JVM, and the Reactive implementation framework is the most typical implementation:
Reactive Streams / Java 9 is a very low-level convention that provides both the Publisher and Subscriber interfaces. Java 9 provides Spring API support for Spring Framework 5.0 / Reactor
Spring 5, Reactive-based Reactor framework, and gradually builds a complete Reactive technology stack, such as WebFlux, similar to Spring MVC features.
Netflix open source technology
Why is there such implementations are talking about how the Reactor
Blocking of Can of Be wasteful
obstruction cause performance bottlenecks and waste of resources to increase the thread may cause resource contention and The parallel way of concurrency is not a silver bullet (cannot solve all problems)
Understand the drawbacks of blocking Understand the complexity of parallelism Asynchronous
Asynchronicity to at The Rescue?
Callbacks to solve non-blocking scheme, however difficult the combination between them, and quickly guided to the code “Callback Hell” point of no return
Futures relative Callbacks a little better, but still can not be combined , but CompletableFuture can improve this deficiency.
Understand “Callback Hell”
CompletableFuture not only supports Future chained operations, but also provides three lifecycle callbacks, namely, execution callback, completion callback, and exception callback (Exception), similar to Spring 4 ListenableFuture and Guava ListenableFuture.
Reactive Streams JVM . http://www.reactive-streams.org/
It is considered that asynchronous system and resource consumption require special processing.
Streaming data capacity is difficult to predict.
Asynchronous programming is difficult to balance the resource consumption between the
complex data source and the consumer.
What is Reactive Programming？
Here are some definitions. Try to understand the meaning of Reactive Programming from different perspectives.
The Reactive Manifesto definition
The first thing to understand is the definition in “The Reactive Manifesto”
Reactive Systems are: Responsive, Resilient, Elastic and Message Driven.
The organization’s definition of Reactive is very simple and its characteristics are reflected in the following keywords: Responsive Resilient Elastic Message Driven (Message Driven)
But this definition focuses on the Reactive system, or the principle of designing a Reactive system.
Wikipedia as the world’s authoritative repository of knowledge, and the fairness of its definition can be guaranteed:
Reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm it is possible to express static (e.g. arrays) or dynamic (e.g. event emitters) data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.
Reference address: https://en.wikipedia.org/wiki/Reactive_programming
Wikipedia believes that Reactive programming is a declarative programming paradigm whose core elements are data streams and its propagation of change. The former is about data structures, including static arrays and dynamics. Event emitters.
Data Streaming: Java 8 Stream
Propagation Changes: Java Observable/Observer
Events/Listening: Java EventObject/EventListener
These techniques are well suited to Wikipedia’s definition of Reactive. So, what is the meaning of the Reactive framework and specifications?
Perhaps the above definition is too abstract and cannot explain the full picture of Reactive.
the definition in the Spring Framework 5
official reference documentation：
The term “reactive” refers to programming models that are built around reacting to change — network component reacting to I/O events, UI controller reacting to mouse events, etc. In that sense non-blocking is reactive because instead of being blocked we are now in the mode of reacting to notifications as operations complete or data becomes available.
Reference address: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-why-reactive
Relative to Wikipedia’s definition, the Spring 5 WebFlux chapter also mentions changing to change, and also states that non-blocking is Reactive.
At the same time, the focus of its definition is on response notification, including operations complete and data becomes available.
As a Reactive web framework, Spring WebFlux naturally supports non-blocking, but it has been implemented in the Servlet 3.1 specification era, including the Servlet 3.1 non-blocking API ReadListener and WriteListener, and the asynchronous context AsyncContext and event listener AsyncListener provided by Servlet 3.0.
These Servlet features provide adaptation to Spring WebFlux, so Spring WebFlux is fully compatible with the Servlet 3.1 container.
Perhaps it is too early to draw conclusions. Let’s take a look at the definition of ReactiveX.
The widely used definition of RxJava in ReactiveX is the Java implementation of ReactiveX.
For the definition of Reactive, ReactiveX is quite authoritative:
ReactiveX extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.
Reference address: http://reactivex.io/intro.html
However, ReactiveX does not directly define Reactive, but uses technical implementation to explain how to implement Reactive.
ReactiveX acts as an extension of the observer pattern, operates on the Sequences of data and/or events by operators (Opators), and masks the following details (abstracting away…), such as the thread API (Exectuor, Future, Runnable). ), synchronization, thread safety, concurrent data structures, and non-blocking I/O.
The focus of this definition focuses on implementation, including design patterns, data structures, data manipulation, and concurrency models.
In addition to design patterns, the Java 8 Stream API has a number of operators, including iterative operations for-each, map/reduce, and collection operations Collectors, as well as parallel and serial operations through the parallel() and sequential() methods. Switching between, also shielding the details of concurrency.
As for the data structure, Stream and the data stream or collection sequence can be marked with an equal sign.
In design mode alone, Stream is an Iterator mode implementation, while ReactiveX is an Observer mode implementation.
Reactor explained this further：
The reactive programming paradigm is often presented in object-oriented languages as an extension of the Observer design pattern. One can also compare the main reactive streams pattern with the familiar Iterator design pattern, as there is a duality to the Iterable-Iterator pair in all of these libraries. One major difference is that, while an Iterator is pull-based, reactive streams are push-based.
Similarly, Reactor also mentions the Observer pattern and the Iterator pattern.
However, it defines Reactive as the Reactive streams pattern and explains the difference between the pattern and the iterator pattern in data reading, that is, the former belongs to push-based and the latter belongs to pull mode (pull). -based).
Is it because of this factor, you must use Reactive?
This may be a little far-fetched.
Personally, the above organizations do not have frank or simple expression to the user, they all use a vague description, how many inevitably make people feel guilty.
Fortunately, André Staltz, from the ReactiveX official. He learned a lot from the little brother in the process of learning Reactive. In his blog, “The introduction to Reactive Programming you’ve been missing” In the middle, he gave a pertinent explanation.
Religed programming is programming with asynchronous data streams.
In a way, this isn’t anything new. Event buses or your typical click events are really an asynchronous event stream, on which you can observe and do some side effects. Reactive is that idea on steroids. You are able to create data streams of anything, not just from click and hover events. Streams are cheap and ubiquitous, anything can be a stream: variables, user inputs, properties, caches, data structures, etc.
“What is Reactive Programming?”
In his article, he pointed out that Reactive Programming is not a new thing, but a common mixture, such as event directors, mouse click events, and so on.
At the same time, the text also refers to keywords such as asynchronous and data streams.
If Java 8 Stream is an iterator pattern and it is not part of the Reactive Programming paradigm, then the Java GUI event/listening is Reactive.
So, where is the need for Java developers to learn RxJava, Reactor, or the Java 9 Flow API?
Therefore, it is very necessary to delve into the use of Reactive Programming.
Reactive Programming The usage scenario
is exactly the same as the definition of Reactive Programming. Each organization has its own word. The following is still using the multi-party citation method to seek the “maximum common divisor” of the Reactive Programming usage scenario.
Reactive Streams JVM usage scenario
The main goal of Reactive Streams is to govern the exchange of stream data across an asynchronous boundary.
The Reactive Streams JVM considers Reactive Streams to be used to manage the exchange of stream data at the asynchronous boundary.
Asynchronously describes its concurrency model, streaming data reflects the data structure, and management emphasizes their coordination between them.
Spring 5 usage scenario
Reactive and non-blocking generally do not make applications run faster. They can, in some cases, for example if using the WebClient to execute remote calls in parallel. On the whole it requires more work to do things the non-blocking way and that can increase slightly the required processing time.
The key expected benefit of reactive and non-blocking is the ability to scale with a small, fixed number of threads and less memory. That makes applications more resilient under load because they scale in a more predictable way.
Spring believes that Reactive and non-blocking usually do not make applications run faster (generally do not make applications run faster), and even increase the processing time. Therefore, its use scenario uses less resources to improve the scalability of the application ( Scale with a small, fixed number of threads and less memory).
ReactiveX usage scenario
The ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. It frees you from tangled webs of callbacks, and thereby makes your code more readable and less prone to bugs.
The usage scenario described by ReactiveX is different from that of Spring. It does not start with performance, but rather the readability of the code and the reduction of bugs, explaining the value of Reactive Programming.
At the same time, the core features of its framework are emphasized: asynchronous, same sort, and composable operations.
It also indirectly illustrates the limitations of Java 8 Stream in combining operations, as well as the lack of operators.
Reactor’s usage scenario
Composability and readability
Data as a flow manipulated with a rich vocabulary of operators
Nothing happens until you subscribe
Backpressure or the ability for the consumer to signal the producer that the rate of emission is too high
High level but high value abstraction that is concurrency-agnostic
Reactor also emphasizes composability and readability and high level abstraction, and explicitly indicates that it provides a rich vocabulary of operators to make up for the short API of the Stream API. Support Backpressure operations, provide data producers and consumers with message mechanisms to coordinate production and sales imbalances between them.
At the same time, Reactor uses the mechanism of Nothing happens until you subscribe to implement the data push mechanism that Stream does not have.
WebFlux usage scenario
Long-term asynchronous execution, once submitted, slowly operate.
Is it suitable for RPC operation?
Task-based, a small number of threads, multiple tasks for a long time, to achieve scalability.
Mono: Single Data Optional 0:1, RxJava : Single
Flux : Multi-Data Collection, Collection 0:N , RxJava : Observable
Functional programming non-blocking (synchronous/asynchronous) away from the Servlet API
API Servlet HttpServletRequest
No longer rely heavily on servlet containers (compatible)
Container Tomcat Jetty
Spring Cloud Gateway -> Reactor
Spring WebFlux -> Reactor
Zuul2 -> Netty Reactive
Reactive Programming, an extension of the Observer pattern, differs from the traditional way of imperative programming to pull data synchronously, such as iterators.
Instead, it uses a scheme in which data publishers push to asynchronously or asynchronously to Data Streams.
When the Data Steams subscriber listens for propagation changes, it responds immediately.
At the implementation level, Reactive Programming can combine functional programming to simplify the bloat of object-oriented language grammar, shield the complex details of concurrent implementation, and provide an orderly operation of the data stream, thereby improving the readability of the code and reducing the occurrence of Bugs.
At the same time, Reactive Programming combined with Backpressure technology to solve the problem that the data generated by the publisher is higher than the consumption of the subscriber.