Common problems when learning WebFlux

Preface

Only a bald head can become stronger.
The text has been included in my GitHub selected article, welcome to Star: https://github.com/ZhongFuCheng3y/3y

Looking back on my introduction to WebFlux in the previous article, if students who have not read it are recommended to read this article again, the previous article took a lot of my effort~~

  • WebFlux, which can be understood by laymen, has missed the
    beginning of the blood loss and another picture, the content depends on editing:

Common problems when learning WebFlux
This article is mainly about some questions I had about WebFlux when I was a beginner. I wonder if you have any corresponding questions when you read the last article?

The main motivation for learning WebFlux this time is to share in the company group and write a PPT. Students in need can get it by replying to "PPT" under my official account (Java3y).

1. It can be asynchronous and non-blocking, why use WebFlux?

I believe students who have relevant knowledge know that Servlet 3.1 already supports asynchronous non-blocking.

We can implement asynchronous in a self-maintaining thread pool

  • To put it bluntly, the thread of Tomcat processes the request, and then distributes the request to the self-maintaining thread for processing, and the request thread of Tomcat returns
@WebServlet(value = "/nonBlockingThreadPoolAsync", asyncSupported = true)
public class NonBlockingAsyncHelloServlet extends HttpServlet {

    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 50000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100));

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        AsyncContext asyncContext = request.startAsync();
        ServletInputStream inputStream = request.getInputStream();
        inputStream.setReadListener(new ReadListener() {
            @Override
            public void onDataAvailable() throws IOException {
            }
            @Override
            public void onAllDataRead() throws IOException {
                executor.execute(() -> {
                    new LongRunningProcess().run();
                    try {
                        asyncContext.getResponse().getWriter().write("Hello World!");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    asyncContext.complete();
                });
            }
            @Override
            public void onError(Throwable t) {
                asyncContext.complete();
            }
        });
    }
}

The flow chart is as follows:

Common problems when learning WebFlux
Asynchronous non-blocking diagram
source of the above example:

protected void doGet(HttpServletRequest request,
                     HttpServletResponse response) throws ServletException, IOException {
    long t1 = System.currentTimeMillis();

    // 开启异步
    AsyncContext asyncContext = request.startAsync();

    // 执行业务代码(doSomething 指的是处理耗费时间长的方法)
    CompletableFuture.runAsync(() -> doSomeThing(asyncContext,
                                                 asyncContext.getRequest(), asyncContext.getResponse()));

    System.out.println("async use:" + (System.currentTimeMillis() - t1));
}

When dealing with complex logic, whether it is a callback or CompletableFuture, the code is more complicated (the code is large and not easy to understand), and WebFlux uses Reactor reactive flow, which provides a series of APIs for us to go. Processing logic is very convenient.

Common problems when learning WebFlux
Callback hell is
more important:

  • WebFlux can be used like SpringMVC, which can greatly reduce the cost of learning
  • WebFlux can also be programmed using Functional Endpoints. Generally speaking, it is more concise and easier to write than callback/CompletableFuture.
    Common problems when learning WebFlux
    The technical use seamlessly with SpringMVC is
    worth mentioning:

If the web container uses Tomcat, then it uses the servlet async api bridged by Reactor.
If the web container is Netty, then it uses Netty. The
official recommendation is to use Netty to run WebFlux.

2. WebFlux performance issues

We found from the last article that the browser calls the slow processing interface, no matter if the interface is synchronous or asynchronous, the time to return to the browser is the same.

  • Synchronization: When the server receives the request, a thread will process the request until the request is processed and returned to the browser
  • Asynchronous: When the server receives the request, one thread will process the request, and then another thread will be assigned to process the request, and the requested thread will be free.
    The official website also said:

Reactive and non-blocking generally do not make applications run faster

The advantages of using asynchronous non-blocking are:

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

Benefit: Only need to start a small number of thread expansion in the program, rather than horizontally through the cluster expansion. Asynchrony can avoid the thread accumulation caused by file IO/network IO congestion.

Let's take a look at the comparison of throughput and response time between synchronous blocking and asynchronous non-blocking for the same request volume:

Common problems when learning WebFlux
Throughput and RT comparison
note:

  • When the request volume is not large (around 3000), synchronously blocking multi-threaded processing requests, throughput and response time are not behind. (According to the truth, WebFlux may still be behind, after all, it has to do one more processing --> the request is delegated to another thread for processing
  • When the request volume is large, the number of threads is not enough, and synchronous blocking (MVC) can only wait, so the throughput will decrease and the response time will increase (queue).

When Spring WebFlux responds to highly concurrent requests, with the help of asynchronous IO, it can process higher throughput requests with a small number of stable threads, especially when the request processing process is long due to business complexity or IO blocking. , The contrast is more significant.

Three, the actual application of WebFlux

WebFlux requires non-blocking business code. If it is blocked, you need to open a thread pool to run it. In what scenarios can WebFlux replace SpringMVC?

  • Want scenarios with less memory and threads
  • Scenarios where the network is slow or IO problems often occur

SpringMVC and WebFlux are more of a complementary relationship, rather than a replacement. In the blocking scenario, SpringMVC is still SpringMVC, and it is not that SpringMVC is replaced by WebFlux.

Common problems when learning WebFlux

If SpringMVC and WebFlux want to exert the performance of WebFlux, they need to go from Dao to Service, all of which are Mono and Flux. At present, the official data layer Reactive framework only supports Redis, Mongo, etc., without JDBC.

Currently for relational databases, the Pivotal team has open sourced R2DBC (Reactive Relational Database Connectivity), and its GitHub address is:

  • https://github.com/r2dbc
    Currently R2DBC supports three data sources:

  • PostgreSQL
  • H2

  • In general, Microsoft SQL Server , because WebFlux is responsive, you must change the code to be responsive if you want to take advantage of the performance of WebFlux. JDBC is currently not supported (at least MySQL does not support it), and response Formal programs are not easy to debug and write (compared to synchronous programs), so the application scenarios of WebFlux are still relatively few.

Therefore, I think it is more appropriate to use WebFlux at the gateway layer (it was originally a scenario with more network IO)

Now come back and look at the pictures of Spring's official website, isn't it more cordial?

Common problems when learning WebFlux
Spring official website introduction map
reference materials:

As mentioned earlier, WebFlux provides two modes for us to use, one is SpringMVC annotated, the other is called Functional Endpoints

Lambda-based, lightweight, and functional programming model

In general, it is to use WebFlux with Lambda and streaming programming. If you ask me: Is it necessary to learn? In fact, I think it can be left first. I think there are still relatively few application scenarios for WebFlux, and it’s not difficult to learn when it’s actually used. Anyway, it’s just to learn some APIs~

With the foundation of Lambda expression and Stream, it is not a problem to learn when you really use it~

The following is an example of using WebFlux through annotations:

Common problems when learning WebFlux
Using WebFlux through annotations The
following is an example of using WebFlux through Functional Endpoints:

Route distributor, equivalent to annotation GetMapping...

Common problems when learning WebFlux
The routing distributor
UserHandler is equivalent to UserController:

Common problems when learning WebFlux
UserHanler

At last

  • ~~
    The main motivation for learning WebFlux this time is to share in the company group and write a PPT. Students in need can get it by replying to "PPT" under my official account (Java3y).

Two years of painstaking articles: "Interview Questions", "Basics" and "Advanced" are all here!

Common problems when learning WebFlux
More than 300 original articles technical articles
massive video resources
exquisite mind map
face questions
press scan code may be concerned about obtaining
watching and sharing is very important to me! Common problems when learning WebFlux
It is not easy to create. Your support and recognition is the greatest motivation for my creation. See you in the next article! Seek likes and attention️ Seek to share and stay

Guess you like

Origin blog.51cto.com/15082392/2590295