preface

Only a bald head can be strong.

Star: github.com/ZhongFuChen…

To review my introduction to WebFlux, if you haven’t read it, please read it again. I put a lot of effort into the last article

  • The layman can understand WebFlux and miss the blood loss

Here’s another picture to start with, all edited:

This article mainly deals with some questions about WebFlux when I was a beginner. I wonder if you have any corresponding questions when you read the article.

The main motivation for learning WebFlux this time was sharing within the company group. I wrote a PPT, which can be obtained by replying “PPT” under my official account (Java3y).

1. Why use WebFlux when you can implement asynchronous non-blocking?

As you know, Servlet 3.1 already supports asynchronous non-blocking.

Asynchrony can be implemented as a self-sustaining thread pool

  • Basically, the Tomcat thread processes the request, and then dispatches the request to the self-maintained thread, which returns the request
@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(a) throws IOException {}@Override
            public void onAllDataRead(a) 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(); }}); }}Copy the code

The flow chart is as follows:

The examples above come from:

  • www.cnblogs.com/davenkin/p/…

For simplicity, we can also use the CompletableFuture class provided in JDK 8, which makes it easy to handle asynchronous calls.

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

    // Enable asynchrony
    AsyncContext asyncContext = request.startAsync();

    // Execute business code (doSomething is a method that takes a long time to process)
    CompletableFuture.runAsync(() -> doSomeThing(asyncContext,
                                                 asyncContext.getRequest(), asyncContext.getResponse()));

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

Copy the code

When dealing with complex logic, both callback and CompletableFuture will be complicated in code writing (large amount of code is not easy to understand), while WebFlux uses Reactor response flow, which provides a series of APIS for us to process logic, which is very convenient.

More importantly:

  • WebFlux can be used in much the same way as SpringMVC, reducing learning costs significantly
  • WebFlux can also be usedFunctional EndpointsWay of programming, generally speaking, or thanThe callback/CompletableFutureBe concise and easy to write.

It is worth mentioning that:

If Tomcat is used for the Web container, the Reactor bridge servlet Async API is used for the Web container. If Netty is used for the Web container, it is used for the Netty, which is built to support Reactive

The official recommendation is to run WebFlux using Netty

2. WebFlux performance problems

As we saw in the previous article, when a browser calls a slow interface, whether the interface is synchronous or asynchronous, the time returned to the browser is the same.

  • Synchronization: The server receives a request, and a thread processes the request until it is processed and returned to the browser
  • Asynchrony: The server receives a request, one thread processes the request, and then assigns another thread to handle the request.

The official website also says:

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

The benefits 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

Benefits: Only a small number of thread extensions need to be initiated within the program, rather than horizontally through the cluster. Asynchrony can avoid thread accumulation caused by file I/O/ network I/O blocking.

Let’s look at throughput and response times for synchronous blocking versus asynchronous non-blocking for the same number of requests:

Note:

  • When the number of requests is not large (3000 or so), synchronous blocking multithreading processing requests, throughput and response time are not behind. Logically, WebFlux might be a bit behind, after all, with an extra step of processing-->Delegate the request to another thread for processing
  • When the number of requests is high, there are not enough threads and synchronous blocking (MVC) can only wait, so throughput decreases and response time increases (queuing).

When Spring WebFlux deals with highly concurrent requests, it can process requests with higher throughput with a small number of stable threads by means of asynchronous IO, especially when the request processing takes a long time due to complex services or IO blocking.

3. Application of WebFlux

WebFlux requires non-blocking business code, and if it does, it needs to open its own thread pool to run it. In what scenarios can WebFlux replace SpringMVC?

  • You want scenarios with less memory and fewer threads
  • The network is slow or I/O problems occur frequently

SpringMVC and WebFlux are more complementary than a replacement. Blocking scenario the SpringMVC is still SpringMVC, it’s not WebFlux replacing SpringMVC.

If you want to give full play to the performance of WebFlux, you need to use Mono and Flux, from Dao to Service. Currently, the official data layer Reactive framework only supports Redis and Mongo, but not JDBC.

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

  • github.com/r2dbc

Currently R2DBC supports three data sources:

  • PostgreSQL
  • H2
  • Microsoft SQL Server

In general, because WebFlux is reactive, to get the best out of WebFlux requires changing your code to be reactive, which JDBC currently does not support (at least not MySQL), and reactive programs are difficult to debug and write (as opposed to synchronous programs). So there are still relatively few application scenarios for WebFlux.

Therefore, I think it is appropriate to use WebFlux at the gateway layer (which is the scenario with more NETWORK IO).

Now look back at the picture on the Spring website, isn’t it more intimate?

References:

  • [blog. Lovezhy. Cc / 2018/12/29 /… (blog. Lovezhy. Cc / 2018/12/29 /…).

Is it necessary to learn Functional Endpoints programming mode?

As mentioned earlier, WebFlux provides two modes to use, one annotated by SpringMVC and one called Functional Endpoints

Lambda-based, lightweight, and functional programming model

In general, WebFlux is used in conjunction with Lambda and streaming programming. If you ask me: Is it necessary to learn? Actually, I think we can leave it. I think there are still few WebFlux application scenarios, and it is not difficult to learn when you really use it. Anyway, just learn some API ~

There are Lambda expressions and Stream foundations, so it’s not a problem to learn when you actually use them

Here is an example of using WebFlux via annotations:

Here is an example of using WebFlux through Functional Endpoints:

Route dispatcher, equivalent to annotated GetMapping…

UserHandler, equivalent to UserController:

5. Actual usage scenarios of WebFlux

In general, because WebFlux is reactive, to get the best out of WebFlux requires changing your code to be reactive, which JDBC currently does not support (at least not MySQL), and reactive programs are difficult to debug and write (as opposed to synchronous programs). Older projects are also unlikely to push dependencies directly up to Spring5.0, so there are still relatively few WebFlux scenarios (in my opinion).

WebFlux is suitable for the gateway layer (it is the scenario with a lot of NETWORK IO)

  • The SpringCloud Gateway is implemented based on WebFlux

The last

Server 89/ year, 229/3 years, buy to send yourself, send my girlfriend for the New Year immediately more appropriate, bought to build a project to see the interviewer also sweet, but also familiar with the technology stack, (old users with family accounts to buy, I use my girlfriend 😂). Scan or click to buy

Build tutorial, from 0 to take you step by step to build😂

The main motivation for learning WebFlux this time was sharing within the company group. I wrote a PPT, which can be obtained by replying “PPT” under my official account (Java3y).

This has been included in my GitHub featured articles, welcome to Star: github.com/ZhongFuChen…

Happy to export dry Java technology public number: Java3y. The public account has more than 300 original technical articles, massive video resources, beautiful brain map, attention can be obtained!

Thank you very much talent can see here, if this article is written well, feel “three crooked” I have something to ask for praise for attention ️ to share 👥 to leave a message 💬 for warm male I really very useful!!

Creation is not easy, your support and recognition, is the biggest motivation for my creation, we will see you in the next article!