Webflux快速入门

引用于
https://www.cnblogs.com/niechen/p/9303451.html
下边的评论很精彩

SpringWebflux是SpringFramework5.0添加的新功能,WebFlux本身追随当下最火的Reactive Programming而诞生的框架,那么本篇就来简述一下这个框架到底是做什么的

一、关于WebFlux
  我们知道传统的Web框架,比如说:struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上,因此它的运行环境的可选择行要比传统web框架多的多。

  根据官方的说法,webflux主要在如下两方面体现出独有的优势:

  1)非阻塞式

    其实在servlet3.1提供了非阻塞的API,WebFlux提供了一种比其更完美的解决方案。使用非阻塞的方式可以利用较小的线程或硬件资源来处理并发进而提高其可伸缩性

  2) 函数式编程端点

    老生常谈的编程方式了,Spring5必须让你使用java8,那么函数式编程就是java8重要的特点之一,而WebFlux支持函数式编程来定义路由端点处理请求。

二、SpringMVC与SpringWebFlux
我们先来看官网的一张图:

  它们都可以用注解式编程模型,都可以运行在tomcat,jetty,undertow等servlet容器当中。但是SpringMVC采用命令式编程方式,代码一句一句的执行,这样更有利于理解与调试,而WebFlux则是基于异步响应式编程,对于初次接触的码农们来说会不习惯。对于这两种框架官方给出的建议是:

  1)如果原先使用用SpringMVC好好的话,则没必要迁移。因为命令式编程是编写、理解和调试代码的最简单方法。因为老项目的类库与代码都是基于阻塞式的。

  2)如果你的团队打算使用非阻塞式web框架,WebFlux确实是一个可考虑的技术路线,而且它支持类似于SpringMvc的Annotation的方式实现编程模式,也可以在微服务架构中让WebMvc与WebFlux共用Controller,切换使用的成本相当小

  3)在SpringMVC项目里如果需要调用远程服务的话,你不妨考虑一下使用WebClient,而且方法的返回值可以考虑使用Reactive Type类型的,当每个调用的延迟时间越长,或者调用之间的相互依赖程度越高,其好处就越大

  我个人意见是:官网明确指出,SpringWebFlux并不是让你的程序运行的更快(相对于SpringMVC来说),而是在有限的资源下提高系统的伸缩性,因此当你对响应式编程非常熟练的情况下并将其应用于新的系统中,还是值得考虑的,否则还是老老实实的使用WebMVC吧

三、Reactive Spring Web
  在这里定义了最基本的服务端接口:HttpHandler和WebHandler

  HttpHandler
  HttpHandler定义了最基本的处理Http请求行为,这个接口主要作用是处理Http请求并将结果做出响应,下面这个表格是说明了Server API的使用方式及何种方式进行响应式流支持的:
WebHandler
  WebHandler定义了Web请求必要一些处理行为,大家不妨想想看:WebFlux已经脱离了Servlet API,那么使用WebFlux时遇到会话机制怎么办,想要对请求过滤处理怎么办或者想要处理静态资源怎么办等等,那么WebHandler就是做这个事情的。其实在HttpHandler的基本实现类通过适配器模式及装饰模式也间接的实现了WebHandler接口:

  WebHandler常见的实现类,我在这里列举一下:

   WebHandlerDecorator:WebHandler的装饰器,利用装饰模式实现相关功能的扩展

   HttpWebHandlerAdapter: 进行Http请求处理,同时也是HttpHandler的实现类

   FilteringWebHandler:通过WebFilter进行过滤处理的类,类似于Servlet中的Filter

   ExceptionHandlingWebHandler: 针对于异常的处理类

   ResourceWebHandler:用于静态资源请求的处理类

   DispatcherHandler:请求的总控制器,类似于WebMVC中的DispatcherServlet

下边的评论
1 有个困惑:flux 真的能让业务请求响应更快吗?并不觉得。

传统mvc:主线程接收到request --> 【准备数据(时间长)】--> 给用户返回数据。
整个过程是单线程阻塞,所以用户感觉等待时间长。

flux是异步模式: 主线程在接收到request --> 立刻返回
(所以性能测试出来的响应时间是很短,是个不变的常数,不随用户数量增加变化)
但是,真实数据还没有准备好,它会开启一个新worker线程去做实际的准备数据工作(这才是真正的业务操作),等worker线程完成工作,用户才收到真实数据。

所以,从整体上来讲,flux更快吗? 感觉只是抖个机灵而已。实际速度由于更多的线程开销应该更慢了才对。

这个问题很好,webflux在spring官网里明确告诉我们并不是提高性能:
Reactive and non-blocking generally do not make applications run faster.
它只是说明,webflux可以在有限的资源下提高系统的吞吐量和伸缩性:
The key expected benefit of reactive and non-blocking is the ability to scale with a small, fixed number of threads and less memory.
2 一台服务器,一秒钟请求3000次服务器崩溃了。但是增加吞吐后,一秒接受请求5000次。
3 异步不仅仅是抖机灵。同步会阻塞,然后依靠系统多线程来切换。而异步的话,递交,然后忙别的事情去了,不占用这部分通信的资源,等待处理完成再返回。会提升性能滴
4 感觉webflux的作用就跟Nginx差不多。
原本spring mvc是同步阻塞的,相当于一个商场,客人进去购物必须有导购员跟着。商场外面有5个导购,来一个客人,就有一个导购员跟着他,直到他购物完毕出去,一趟要花个几十分钟。如果一下子来了10个人,那导购员就不够用了,客人就只能在门外等,或者被拒绝进入。
但是现在webflux异步非阻塞,就相当于门口不要导购员了,只留1个礼仪小姐,商场内部安排4个导购员。礼仪小姐只需要迎接客人进入商场,客人进入商场后就交给导购员带客人去购物,购物完后导购员将客人交给礼仪小姐带客人离开。如果一下子来了10个人,就让礼仪小姐一一带入商场内休息【排队】,导购员依次带他们去购物。

同步阻塞、异步非阻塞其实指的是负责接收http连接的线程。跟工作线程无关。总体业务花费的时间始终保持不变。只是可以接收的http网络链接多了。

——知识在于分享! PS:本随笔属个人学习小结,文中内容有参考互联网上的相关文章。如果您博文的链接被我引用,我承诺不会参杂经济利益!
原文地址:https://www.cnblogs.com/jianzhixuan/p/14506326.html