前言
参考书是 龙中华 《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 框架 仅此而已。