vlambda博客
学习文章列表

90-webflux响应式编程怎么去理解?


  • 前言

    • 1.什么是响应式编程:

    • 2.使用spring-boot-starter-webflux:

    • 3.Jetty、tomcat、undertow、netty怎么区分:

  • 总结


前言

现在网关都采用spring-cloud-gateway,我们看使用过程中发现编码已经采用响应式编程,直接集成了spring-boot-starter-webflux依赖,这就捎带着把响应式编程带火了一把。本文结合我的理解对响应式编程做一个总结性的介绍,希望能帮助到大家。

1.什么是响应式编程:

提到响应式编程,跟传统的编程区别可能刚开始不太好区分,其中最重要的区别就是传统的是阻塞的,响应式编程是非阻塞异步。官网介绍响应式编程:

In computing, reactive programming is an asynchronous programming paradigm 
concerned with data streams and the propagation of change. 
This means that it becomes possible to express static (e.g. arrays) or 
dynamic (e.g. event emitters) data streams with ease via the employed 
programming language(s), and that an inferred dependency within the 
associated execution model exists, which facilitates the automatic propagation of 
the change involved with data flow.

在计算机领域,响应式编程是一个专注于数据流和变化传递的异步编程范式。
这意味着可以使用编程语言很容易地表示静态(例如数组)或动态(例如事件发射器)数据流,
并且在关联的执行模型中,存在着可推断的依赖关系,这个关系的存在有利于自动传播与数据流有关的更改。

可能这段话还是不好理解,但是可以着重看下数据变化,响应式编程就是基于数据变化的新的编程模式,实现异步非阻塞,就是当请求来了之后进行订阅数据的变化,后续业务处理发布变化,然后进行监听到变化,进行响应。而传统的springmvc则是创建新线程等待阻塞,知道请求完毕,释放线程的过程。

2.使用spring-boot-starter-webflux:

比较经典的图示:从图中我们可以看到基于spring-webmvc和spring-webflux的路线和区别。其中webflux默认是使用netty的通信框架作为web容器,相比较tomcat,netty的优势不再赘述了,并发高、传输快、封装好,其中netty的零拷贝等等。我们在使用webflux的时候注意两个需要经常使用的对象Mono和Flux:

Mono Flux
实现发布者,并返回 0 或 1 个元素,即单对象 实现发布者,并返回 N 个元素,即 List 列表对象

3.Jetty、tomcat、undertow、netty怎么区分:

tomcat:市场占有率仍然非常高,虽然性能上跟其他web服务器比较会有欠缺,但是因为其成熟,实践度很高。undertow和Jetty都是基于NIO实现高并发的轻量级服务器,支持servlet3.1和websocket springboot2以后增加了webflux的web容器,而webflux是基于netty的,netty是nio的,加上其零拷贝的实现,保证其性能上占据优势。

3.1 springboot中使用jetty:

<!-- web剔除tomcat容器= -->
<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.5.10.RELEASE</version>
 <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 引入Jetty容器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

3.2 springboot中使用undertow:

<!-- 添加spring-boot-starter-web,默认使用tomcat作为web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 去除tomcat,将undertow作为容器 -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

3.2 springboot中使用Webflux/Netty:

<!--<dependency>-->
   <!--<groupId>org.springframework.boot</groupId>-->
   <!--<artifactId>spring-boot-starter-web</artifactId>-->
  <!--</dependency>-->
  <!--基于响应式编程【改】增加“flux”四个字符-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-webflux</artifactId>
  </dependency>

总结

其实Spring提供的webflux框架简化了我们操作Netty使用的复杂性,提供了Reactor Netty库,因为网关性能的要求,所有spring-cloud-gateway直接集成了webflux,使用Netty的nio的特性极大的满足了网关高并发,高性能要求的场景,个人觉得不见得响应式编程未来会遍地开发,但是网关这种特殊的场景确实比较适合响应式编程的应用。