SpringBoot Webflux解析

article/2025/8/29 2:01:23

1. Webflux介绍

        Webflux是一种异步非阻塞的IO模型,当有请求过来时,它会将请求交由worker线程去处理,这样就可以极大的提升吞吐量,所以他比较适合用于IO密集型的场景。

        webflux虽然可以给我带来吞吐量的提升,但是同时也带了一些问题,如调试困难,有一定的学习成本,此外目前仅有少数数据库支持异步非阻塞查询,如redis支持,而mysql不支持。它使用netty作为服务端框架,网络通信性能很高,但是我们在准备引入该技术的时候也需要十分谨慎。

在SpringBoot官方也给出了相关建议:

  1. 如果你的项目目前使用的时SpringMvc且运行良好那就没有必要使用Webflux,SpringMvc的编程方式易编写也易理解,同时还有大量的类库可供使用。
  2. 如果你已经使用了异步非阻塞的编程方式,那么可以切换到webflux,webflux提供了更加丰富的功能
  3. 如果你对轻量级、java8的lambdas函数式编程的web框架感兴趣,那么在一些小型项目上可以使用。
  4. 在微服务架构下,你可以同时使用springmvc和wenflux,它们的在基础注解模型上是一样的
  5. 如果你依赖了持久化层的API(JDBC、JPA)或者网络API,对于基础架构来说springmvc是最好的选择
  6. 如果你的springmvc应用调用远程服务,可以尝试使用webclient。你可以直接从controller方法中获取到reactive类型。
  7. 如果你在一个大型团队,那么要谨慎考虑切换的成本,webflux的学习曲线还是比较陡峭。

2. Reactor框架介绍

Springboot官网为我们提供了关于reactive 的技术栈,如下图所示:

Webflux主要技术依赖有:Reactive Streams反应式编程标准和规范、基于reactive streams的反应式编程框架和以reactive为基础实现web领域的反应式编程框架。

Reactive Streams是一套基于jvm面向流式类库的标准和规范,它要求:

  1. 具有处理无限数量数据的能力
  2. 按序处理数据
  3. 异步非阻塞的传递数据
  4. 必须实现非阻塞的背压

Reactive api规范组件:

  1. Publisher:数据发布者
  2. Subscriber:数据订阅者
  3. Subscription:订阅信号
  4. Processor:处理器(包含了发布者和订阅者的混合体)

Reactive操作符:

1. Map操作符:对每一个数据进行转换操作,如,每个数据除2,当处理完交由消费端。

2. Flatmap操作符:有时候我们一个元素需要映射成一个元素序列,将该序列压平然后合并成更大的元素序列。

3. Filter操作符:指将不符合条件的元素过滤掉,不发给消费端。

 

4. Zip操作符:将两个publisher的序列合并输出。 

 

Reactor与java 8 Stream区别:虽然从写法来看感觉一样,其实是形似神不似。Reactor采用的是push模式,服务端推送数据给客户端消费,它是异步反应式模式;而stream是pull模式是同步的命令式程序。

Reactor线程模型:

1. 创建线程方式:

Schedulers.immediate():当前线程

Schedulers.single():可重用的单线程

Schedulers.elastic():弹性线程池

Schedulers.parallel():固定大小线程池

Schedulers.fromExecutorService():自定义线程池

2. 线程切换总结:

  1. PublishOn:它将上游信号传给下游,同时改变后续的操作符的执行所在线程,直到下一个publishOn出现在这个链上。
  2. SubscribeOn:作用于向上的订阅链,无论处于操作链的什么位置,他都会影响到源头的线程执行环境,但不会影响后续的publishOn

3.Webflux处理流程解析

        首先我们看一下SpringMvc的请求处理流程,当请求进来之后会进入到DispatcherServlet,DispatcherServlet会将请求转发给handlerMapper找到映射器,之后通过HandlerAdapter找到对应的handler处理请求,处理完之后会调用ViewResolver视图解析器对结果进行解析,然后通过View视图解析器进行渲染。在Webflux中也存在类似DispatcherServlet的存在,那就是DispatcherHandler。

 

        DispatcherHandler类中的核心方法是handle,该方法的参数是ServerWebExchange,该类的作用是Http请求和响应相互的纽带,该类中不仅提供了获取ServerHttpRequest和ServerHttpResponse,而且还为服务端处理请求时提供了相关的属性的方法,如获取request attribute、session等,handler处理的主要流程是先获取handlerMappings,然后调用concatMap方法获取对应的HandlerMapping,该方法是保证顺序的,如果在controller和RouterFunction同时存在相同的path,那么只会执行第一个,也就是routerFunction的handler,然后执行该方法并处理返回的结果。

        DispatcherHandler实现了ApplicationContextAware接口,在setApplicationContext方法中调用了initStrategies方法,该方法完成了DispatcherHandler的准备工作。

   该方法首先获取所有的HandlerMapping实现类,有三类,分别是requestMappingHandlerMapping主要处理SpringMvc注解方式;第二个是routerFunctionMapping,这个是实现RouterFunction接口,通过此种方式配置路径映射的关系;第三个是resourceHandlerMapping,其类型为SimpleUrlHandlerMapping,主要处理通过url匹配路径,如/webjars/**、/**相关的ResourceWebHandler。

        其次获取HandlerAdapter的实现类,Handler主要是根据@RequestMapping的注解配置的path找到对应的方法,然后执行此方法。 

        最后获取所有实现了HandlerResultHandler接口的子类,共有4种实现,ResponseEntityResultHandler主要处理HttpEntity和ResponseEntity;ResponseBodyResultHandler主要处理@ResponseBody标注的返回结果;ViewResolutionResultHandler主要处理返回值为void、String、View、Model、Map、Rendering和ModelAndView。 

        因此,RouterFucntion实现了InitilizationBean,所以先会调用afterPropertiesSet方法,整个初始化流程为:

至此,完成了Webflux的准备工作,那么接下来看下对请求的处理流程:

 

4.总结

        webFlux采用异步非阻塞模型,相比于SpringMvc可以极大的提升吞吐量。但是也不是没有副作用,像学习曲线高、调试难以及不支持jdbc等数据库,而NoSql数据库相对支持较为完善,而且它可以和SpringMvc一起使用。

        WebFlux采用reactor作为响应式编程框架。Reactor采用异步非阻塞式模型,而非同步命令式编程。

 

 

 

 


http://chatgpt.dhexx.cn/article/UAxMFRZs.shtml

相关文章

Webflux快速入门

传统的Web框架,如struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框…

Spring-webflux 响应式编程

热爱可抵漫长岁月 文章目录 1. 前言2. Spring-webflux简介3. 什么是“响应式”4. Spring-webflux的响应式API5. Spring MVC 还是 WebFlux?6. 并发模型7. webflux使用8. 测试 1. 前言 Spring 提供了两个并行堆栈。一种是基于带有 Spring MVC 和 Spring Data 结构的 …

Spring Webflux - 01 MVC的困境

文章目录 Spring MVC的困境Servlet 异步请求缓解线程池压力Servlet 3.0 异步请求处理Code 演示工程pom配置文件启动类同步servlet演示 异步servlet辅助Code演示 Tomcat 请求处理流程以及异步请求工作原理 Spring MVC的困境 我们先看一段工作中大家常见的代码 RestController …

WebFlux的使用

什么是WebFlux springWebFlux 是 SpringFrameworlk5.0 添加的新功能,它是完全非阻塞的,支持Reactive Stream及背压,可以运行于Netty、Undertow等服务器,及Servlet 3.1容器。 webflux主要在如下两方面体现出独有的优势:…

webFlux入门

今天发现一个特别好的文章,是关于springBoot框架中响应式编程的,那下面就是这位博主所整理的一些干货👇 ------------------------------------------------------------ 1. WebFlux介绍 Spring WebFlux 是 Spring Framework 5.0中引入的新…

WebFlux 简介

目录 一、关于WebFlux 二、SpringMVC与SpringWebFlux 三、Reactive Spring Web HttpHandler WebHandler 四、实现WebFlux 实例 基于Annotated Controller方式实现 WebFluxConfig配置: Controller: Main方法: 函数式编程方式 集成Thymeleaf sp…

Spring Webflux 响应式编程 (二) - WebFlux编程实战

第一章 Reactive Stream 第1节 jdk9的响应式流 就是reactive stream,也就是flow。其实和jdk8的stream没有一点关系。说白了就一个发布-订阅模式,一共只有4个接口,3个对象,非常简单清晰。 什么是背压? 背压是指订阅者…

WebFlux 详解

今天我们开始来学习下 WebFlux,为什么突然要学这个东西? 因为我之前是想学习 Spring Cloud Gateway 来着,然后发现它是基于 Spring5.0SpringBoot2.0WebFlux等技术开发的。所以学之前才要来简单了解下 WebFlux 技术。 然后要学习 WebFlux 时…

Redis常用数据类型及其对应的底层数据结构

Redis数据库 Redis是一种键值(Key-Value)数据库。相较于MySQL之类的关系型数据库,Redis是一种非关系型数据库。Redis存储的数据只包含键和值两部分,只能通过键来查询值。这样简单的存储结构,能让Redis的读写效率非常高(HashMap读写效率都是O…

二. Redis 数据类型

2.1 Redis 字符串 (String) 2.1.1 概述 String 是 Redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。 String 类型是二进制安全的。意味着 Redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。 …

Redis数据类型Hash

文章目录 Hash类型介绍hash 类型数据的基本操作 hash 类型数据操作的注意事项Hash和String类型的区别 有时候我们往往不是在缓存中存一个值,而是选择存一个对象,比如一个购物车消息,我们就需要使用到hash了 Hash类型介绍 新的存储需求&…

Redis数据类型String

文章目录 数据存储类型介绍String类型String类型的基本操作String单数据操作和多数据操作的选择问题string 类型数据的扩展操作数据增加指定范围的值String 设置数据指定的生命周期string 类型数据操作的注意事项 数据存储类型介绍 常用的五个数据类型: string --------------…

Redis数据类型 - 散列(Map)

文章目录 一、散列简介二、散列的基本操作三、散列与字符串比较1、散列键的优点2、字符串键的优点 一、散列简介 散列就是hash或者说Map,Redis的散列键会将一个键和一个散列在数据库中关联起来,可以在散列中设置任意多个字符串键值对,因此通…

redis数据类型插入输出命令

进入客户机:redis-cli 中文字符不能显示:redis-cli --raw、get Course:1:Cname 一、redis数据类型数据的添加 1、String 添加数据:set StringTest(数据名称) “helloword”(数据) 显示数据:get StringTest(数据名称&am…

Redis数据类型及使用场景

转自: http://www.kubiji.cn/juhe-id7106.html Redis数据类型及使用场景 来源: WQTech阅读: 2936 时间:2 小时前 摘要:Redis相比其它的KV数据库,其一大特点是支持丰富的数据类型.它一共支持5种数据类型,下面逐一介绍这…

Redis数据类型与操作命令

1. 键值对数据库 1.1 redis数据结构 redis的数据是 key-value 形式的键值对,其中 key 其实都是字符串的形式,而 value 的数据类型,也就是数据的保存形式,底层实现的方式就用到了数据结构。 所以我们一直说的“redis五种数据结构…

Redis数据类型

文章目录 STRINGLISTSETHASHZSET Redis主要有5种数据类型,包括String,List,Set,Zset,Hash,满足大部分的使用要求,Redis各数据类型的使用场景可以参考Redis使用场景 数据类型可以存储的值操作ST…

redis数据类型(5种)和底层实现

redis数据类型(5种)和底层实现 Redis的特点 要用好Redis,首先要明白它的特点: 读写速度快。redis官网测试读写能到10万左右每秒。速度快的原因这里简单说一下,第一是因为数据存储在内存中,我们知道机器访问内存的速度是远远大于…

Redis数据类型及编码

Redis数据类型及编码 说到Redis的数据类型,我们大概会很快想到Redis的5种常见的数据类型:字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted Set),以及他们的特点和运用场景及常用命令。不过在讲五大数据类型之前&#x…

Redis 基础 -- Redis数据类型之set

文章目录 1. Redis数据类型之set1.1 set类型介绍1.2 set类型基本操作1.3 set 类型数据的扩展操作:获取随机的数据1.4 set 类型数据的扩展操作:集合的交、并、差集1.4.1 sinter命令1.4.2 sunion命令1.4.3 sdiff命令1.4.4 sinterstore命令1.4.5 sunionstor…