SpringMVC的孪生兄弟WebFlux

摘要:
非阻塞在Servlet 3.1中提供了一个非阻塞API,WebFlux有自己的一组方法。使用非阻塞方法,可以使用较小的线程或硬件资源来处理并发的函数式编程端点。Spring 5必须配备java 8。函数式编程是java 8的重要特性之一。WebFlux支持函数式编程来定义处理请求的路由端点。

一、入门文字介绍

官方口水话简短翻译:

  Spring WebFlux是一个非阻塞的Web框架,用于利用多核,短时间可一处理大量并发连接。

非阻塞式

  在servlet3.1提供了非阻塞的API,WebFlux为之有自己的一套手段,

  使用非阻塞的方式可以利用较小的线程或硬件资源处理并发

函数式编程端点

  Spring5必须配备java8,函数式编程就是java8重要的特点之一,

  WebFlux支持函数式编程来定义路由端点处理请求。

二、入门小Demo Test

  创建一个Spring Boot项目,版本要求2.0以上,需要下面的依赖,Spring Reactive Web  替代了Web依赖

    SpringMVC的孪生兄弟WebFlux第1张

  看看我们的处理器:Controller

    抽一个方法出来,待会儿会使用到,这个方法假如就是我们一个比较耗时的逻辑操作

      SpringMVC的孪生兄弟WebFlux第2张

    然后看我们的处理器 @Slf4j   @RestController

      SpringMVC的孪生兄弟WebFlux第3张

      我们定义了两个处理器,一个就是普通的处理器,一个是使用了WebFlux的处理器,

      然后我们观察我们的控制台日志情况:

      SpringMVC的孪生兄弟WebFlux第4张 ...SpringMVC的孪生兄弟WebFlux第5张

    • 有没有发现什么一样,当然我们的页面都是一样的,需要在五秒后才会有结果,但是你观察控制台

    • 发现下面那个打印的时间间隔很短有没有,并没有像上面那个一样等待五秒才打印

    • 下面使用WebFlux的请求的耗时操作没有阻塞处理器的执行,也就是说耗时没能影响到处理器,

    • 这样的话,处理器就可以同时接很多请求了,反正也不会堵塞,

    • 虽然对于请求的响应页面数据来看,没有任何差别,但是对于处理器来说,其吞吐量将会大大提高

三、修改处理器返回值Flux用法

Mono表示处理器返回的数据为0-1个,Flux表示返回的数据为0-多个

数组转Flux

访问测试: http://localhost:8080/test5?strs=lisi&strs=wangwu

  SpringMVC的孪生兄弟WebFlux第6张

集合转Flux

访问测试:http://localhost:8080/test6?strs=lisi&strs=wangwu&strs=xiongqi

  SpringMVC的孪生兄弟WebFlux第7张

Flux底层不会阻塞处理器的执行

  SpringMVC的孪生兄弟WebFlux第8张

SpringMVC的孪生兄弟WebFlux第9张我们看下面的日志输出:

  SpringMVC的孪生兄弟WebFlux第10张...SpringMVC的孪生兄弟WebFlux第11张

同步Servlet & 异步Servlet

通过上面的小Demo,我们对"非阻塞","异步"应该有了点概念了吧,详细可看我的另一片学习笔记

https://www.cnblogs.com/msi-chen/p/10983927.html

下面我们来测试异步Servlet和同步Servlet的差异

定义一个同步Servlet,也就是普通的Servlet

  SpringMVC的孪生兄弟WebFlux第12张

SpringMVC的孪生兄弟WebFlux第13张定义一个异步Servlet,最后做统一测试

  SpringMVC的孪生兄弟WebFlux第14张

SpringMVC的孪生兄弟WebFlux第15张耗时操作为:

  SpringMVC的孪生兄弟WebFlux第16张

SpringMVC的孪生兄弟WebFlux第17张启动Tomcat,我们进行访问,查看控制台的输出​SpringMVC的孪生兄弟WebFlux第18张

  SpringMVC的孪生兄弟WebFlux第19张

我们观察浏览器的响应,都是在等待5秒后的延迟后才会出结果页面

但是我没得控制台的输出,两个Servlet的业务逻辑耗时为6毫秒和5000多毫秒

同步Servlet阻塞了什么?

当请求到达Tomcat后,Tomcat会为其找到有该请求相匹配的Servlet,并分配一个该Servlet的线程处理该请求,当Servlet中需要处理耗时操作是,当前Servlet线程会被阻塞挂起,所以同步Servlet的业务逻辑阻塞了线程的执行,总共耗时了5000多毫秒

异步Servlet是怎么工作的呢?

先说结果:异步Servlet没有阻塞Servlet线程的执行,而是很快就结束了Servlet线程的调用,又将其投入Servlet线程池,等待新的连接请求,说到这里,那我们的耗时逻辑业务为什么又没有起到耗时的作用呢?因为逻辑耗时代码是另一个线程在执行,但服务端的响应是需要耗时业务逻辑执行完才会响应给客服端的,,也就是说这里分成了两个线程,主线程为没有被阻塞Servlet,次线程在执行耗时逻辑,当次线程执行完后响应给客户端,所以,客户端还是得等5秒才会有响应结果,但是服务端因为Servlet线程早早的就是执行完,在线程池等待了,服务器的吞吐量是不是大大提高了呢?

SpringMVC的孪生兄弟WebFlux第20张

 

免责声明:文章转载自《SpringMVC的孪生兄弟WebFlux》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux 各种软件的安装Linux下用source insight的另一种方式--Samba下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SpringBoot入门篇

一    什么是springboot Spring官网:http://spring.io/projects SpringBoot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品: Springboot不是什么真正意义上的新框架,就像maven整合了所有的jar包,spring boot整合了所有常...

Java多线程学习之任务的创建以及在线程中执行任务

传统的创建任务、驱动任务的方式 1.继承Thread类   通过继承Thead类,并重写run方法,在run方法里面编码具体的任务,调用对象的start方法驱动任务。    public class TestThread extends Thread{ private int count = 5;   //创建介绍String形参的构造器,一般...

4.0中的并行计算和多线程详解(一)

  并行计算部分   沿用微软的写法,System.Threading.Tasks.::.Parallel类,提供对并行循环和区域的支持。 我们会用到的方法有For,ForEach,Invoke。   一、简单使用   首先我们初始化一个List用于循环,这里我们循环10次。(后面的代码都会按这个标准进行循环) Code             Pr...

[ PyQt入门教程 ] PyQt5中多线程模块QThread使用方法

本文主要讲解使用多线程模块QThread解决PyQt界面程序唉执行耗时操作时,程序卡顿出现的无响应以及界面输出无法实时显示的问题。用户使用工具过程中出现这些问题时会误以为程序出错,从而把程序关闭。这样,导致工具的用户使用体验不好。下面我们通过模拟上述出现的问题并讲述使用多线程QThread模块解决此类问题的方法。 PyQt程序卡顿和无法实时显示问题现象 使...

数据库连接池SQLAlchemy中多线程安全问题

数据库连接池SQLAlchemy中多线程安全的问题 1、数据库模块model.py from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker session_factory = sessionmaker(bind=some_engine) Ses...

Kafka 异步消息也会阻塞?记一次 Dubbo 频繁超时排查过程

线上某服务 A 调用服务 B 接口完成一次交易,一次晚上的生产变更之后,系统监控发现服务 B 接口频繁超时,后续甚至返回线程池耗尽错误 Thread pool is EXHAUSTED。因为服务 B 依赖外部接口,刚开始误以为外部接口延时导致,所以临时增加服务 B dubbo 线程池线程数量。配置变更之后,重启服务,服务恢复正常。一段时间之后,服务 B...