前言

参考书是 龙中华 《Spring Boot 实战派》


1、什么是WebFlux

webFlux是从Spring Framework5.0开始引入响应Web框架的与SpringMVC不同的是 不需要 Servlet API 、在完全异步且无阻塞,并通过Reactor项目实现Reactive Streams  规范。WebFlux可以在资源有限的情况下提高系统的吞吐量和伸缩性。(并非提高性能))

这意味着,在资源相同的情况下,WebFlux可以处理更多的请求(不是业务)。

WebFlux除支持RESTfulWEB服务外,还可以用于提供动态HTML内容


2、比较MVC 和 WebFlux

Spring MVC 采用命令式编程的方式,代码被一句一句的执行,便于开发者理解和调试代码

WebFlux 则是基于异步响应式编程。

2.1工作方式

MVC:

MVC的工作流程是:主线程收到请求(request)-》准备数据-》返回数据。

整个过程单线程阻塞,用户感觉时间长是因为在结果处理好之后,才会返回数据给浏览器,因此,如果请求很多,则吞吐量上不去。

WebFlux:

WebFlux的工作流程是:主线程接收到请求-》立刻返回数据和函数的组合(mono或者Flux,不是结果)-》开启一个新Work线程去做实际的数据准备工作,进行真正的业务操作-》work线程完成工作-》返给用户真实数据(结果)

这种方式给人的感觉是响应时间很短,因为返回的是不变的常数,他不随用户数量而变化。


2.2 Spring MVC 和 Spring WebFlux的区别

SpringMVC 和 Spring WebFlux的区别

对比项

Spring MVC

Spring WebFlux

地址(路由)映射

@controller 和@requestmapping 等标准的SpringMVC注解

1、Router Fuctions,提供一套函数式风格的API,用于创建Router,Handler和Filter

2、@Controller。@requestMapping 等标准Spring MVC注解

数据流

Servlet API

Reactive Streams: 一种支持背压(backpressure)的异步数据处理标准流程,主流实现有RxJava 和 Reactor,Spring Webflux默认集成的是Reactor

容器

Tomcat 、Jetty、 Undertow

Netty、tomcat、Jetty、Undertow

I/O模型

同步阻塞的I/O模型

异步非阻塞的I/O模型

吞吐性能



业务处理性能

一样

一样

支持数据库

Nosql  、 SQL

支持Nosql  不支持Mysql的关系型数据库

请求和响应

HTTPServletRequest和 HttpServletReponse

ServerRequest 和 ServerResponse

 


2.3、使用WebFlux的好处

举个栗子:

下面以餐厅“叫号”来比喻阻塞式开发与WebFlux。
假设“海底捞”没有叫号机(前台服务员),店里有200个餐台供客人进餐,如果此时来了201个客人,那么最后一个客人就直接被拒绝服务了。而现在有叫号机,来了200个客人正在用餐,后面再来100个客人,叫号机马上给后面的100个客人每人一个排队号。这样服务就不阻塞了,每个人都立马得到反馈。来再多的人也能立马给排号,但是进餐依然是阻塞的。

回到程序。我们假设,服务器最大线程资源数为200个,当前遇到200个非常耗时的请求,如果再来1个请求时,阻塞式程序就已经处理不了( 拒绝服务)了。而对于WebFlux,则可以做到立即响应(告诉用户等着),然后将收到的请求转发给Work线
程去处理。WebFlux只会对Work线程形成阻塞,如果再来请求也可以处理。其主要应用场景是:在业务处理较耗时的场景中减少服务器资源的占用,提高并发处理速度。对WebFlux的一个简单的理解就是:你来了,我立马应答你,但是服务需要等待;而不是你
来了没人理你,咨询服务半天也回复不了。结论: MVC能满足的场景,就不需要改用WebFlux。WebFlux 和MVC可以混合使用。如果开发/O密集型服务,则可以选择用WebFlux实现。

如果在pom.xml文件中同时引用了spring-boot-starter-web和spring-boot-starter-webflux依赖,则会优先使用spring-boot-starter-web 这时控制态输出的启动日志会提示"tomcat started on port(s):8080 (http)with context path",而使用WebFlux会提示“Netty Started on port(s):8080”


3、认识Mono 和 Flux

3.1、Mono 和 Flux 是什么

1)、Mono和Flux是什么

Mono和 Flux是 Reactor中;两个基本的概念。

Mono 和Flux 属于事件发布者,为消费者提供订阅借口,当有事件发生时,Mono和 Flux 会回调消费者的相应方法,然后通知消费者相应的时间,这也是响应式编程模型。

Mono和Flux用于处理异步数据流,他不像MVC中那样直接返回String/list,而是将异步数据流包装成Mono 或者Flux对象。

2)、Mono 和 Flux 的区别

 1、Flux可以发送很多item。并且这些item可以经过若干算子(operators)后才被订阅

 2、Mono主要用于返回单个数据,Flux用于返回多个数据

比如 要查询一个User,通过id查询,那么返回的是一个User,需要将其包装成Mono<User>。

若需要获取所有的User,一个集合,那么可以包装成Flux<User>,这里的单个数据不是指一个数据,而是指一个封装好的对象,多个数据就是多个对象。

3)、Mono表示包含0或者1个元素的异步序列,在该序列中可以包含3种不同类型的消息通知,正常的包含元素的消息、序列结束的消息,序列出错的消息。当消息通知(正常的包含元素的消息、序列结束的消息、序列出错的消息)产生时,订阅者中有对应的方法,onNext()、onComplete()、onError()被调用。

消息通知

方法(事件订阅者)

正常的包含元素的消息

onNext()

序列结束的消息

onComplete()

序列出错的消息

onError()

4)、Flux表示的是包含0到N个元素的异步序列,在该序列中可以包含与Mono的相同的3中类型的消息通知。

5)、Flux和Mono之间可以进行转换。对一个Flux序列进行技术操作时,得到的结果是一个Mono<Long>对象,把多个Mono序列合并在一起,得到一个Flux对象。


4、开发WebFlux的流程

1、注解式开发流程

WebFlux是响应式框架、其中使用的注解式开发只是Spring团队为了更好的迁移而提供的。和MVC开发模式一样。地址映射也是通过@RequestMapping  提供,@Controller或者@RestController来代替handlera

2、响应式开发流程

 1、创建Handler类

这里的handler类相当于SpringMVC 的Controller层中的方法体,在响应式编程中,只不过请求和响应不再是HttpServletRequest和 HttpServletResponse 而是变成了ServerRequest 和ServerResponse

2、配置RouterFunction

RouterFunction 和 注解@RequestMapping 相似,都用于提供URL路径,RouterFunction的格式也是固定的,第一个参数代表路径,第二个代表方法 合起来将代表URL映射到方法。


结尾:

做了两年开发,发现对Spring Boot 的认知上缺少了很多东西。因此想重新认识 Spring Boot 框架 仅此而已。