当前位置: 首页 > news >正文

Spring Boot 2 快速教程:WebFlux优缺点及性能分析(四)

WebFlux优缺点

【来源DeepSeek】

Spring WebFlux 是 Spring 框架提供的响应式编程模型,旨在支持非阻塞、异步和高并发的应用场景。其优缺点如下:


优点

  1. 高并发与低资源消耗

    • 非阻塞 I/O:基于事件循环模型(如 Netty),使用少量线程处理大量并发请求,避免传统阻塞式模型中的线程上下文切换开销。

    • 资源高效:适合处理大量长连接或延迟敏感型请求(如实时通信、流处理),减少内存和 CPU 的消耗。

  2. 响应式编程模型

    • 背压(Backpressure)支持:通过 Reactive Streams 规范(如 Project Reactor)实现流量控制,防止生产者压垮消费者。

    • 函数式编程风格:提供声明式 API(如 RouterFunction),简化异步逻辑的编写。

  3. 可扩展性

    • 适合微服务架构,能够高效处理服务间的异步通信(如结合 WebClient 调用其他服务)。

  4. 兼容性

    • 支持与传统的 Spring MVC 共存,允许逐步迁移到响应式架构。

    • 适配多种服务器(Netty、Undertow、Servlet 3.1+ 容器)。


缺点

  1. 复杂度高

    • 学习曲线陡峭:响应式编程需要理解 FluxMono、操作符链式调用等概念,调试和错误处理较困难。

    • 代码可读性差:链式调用和异步逻辑可能导致代码难以维护。

  2. 生态兼容性有限

    • 阻塞式库不兼容:大多数传统库(如 JDBC、JPA)是阻塞的,需改用响应式驱动(如 R2DBC、MongoDB Reactive)。

    • 中间件支持不足:部分框架或工具(如 Spring Security)对响应式的支持尚未完全成熟。

  3. 适用场景受限

    • CPU 密集型任务不适用:非阻塞模型对计算密集型操作无优势,甚至可能因线程竞争导致性能下降。

    • 简单业务场景性价比低:对低并发、简单 CRUD 应用,传统 MVC 更易开发和维护。

  4. 调试与监控困难

    • 异步堆栈信息不直观,需依赖专业工具(如 Reactor Debug Agent)定位问题。

    • 传统监控工具(如 Spring Actuator)可能无法直接适配响应式链路。


适用场景

  • 高并发 I/O 密集型服务:如 API 网关、实时消息推送、流处理。

  • 微服务间异步通信:需要高效处理大量并发请求的场景。

  • 延迟敏感型应用:如实时数据分析或金融交易系统。


总结

  • 选择 WebFlux 的条件:需要处理高并发、非阻塞 I/O,且团队熟悉响应式编程。

  • 避免 WebFlux 的情况:业务逻辑简单、依赖传统阻塞库,或团队缺乏响应式经验。

实践证明,使用WebFlux开发接口能够大幅提升接口的吞吐量

相关参数:

  • 测试机器:Linux CentOS6.5 4核16G
  • SpringBoot版本:2.2.2.RELEASE
  • JDK版本:jdk1.8.0_151

本文主要内容如下:

  1. 使用tomcat容器的代码演示
  2. 使用netty容器的代码演示
  3. apachebench(ab)压测接口,对比性能数据
文中代码较多,建议大家收藏后,有时间自己亲自动手开发并压测来验证结果。

tomcat容器下的代码演示

我们先基于tomcat容器来验证传统的SpringMVC以及基于Project Reactor两种方式开发接口的区别。

先来迅速搭建一个基于SpringBoot-2.2.2.RELEASE版本的demo项目,pom.xml核心依赖如下:

SpringBoot父级依赖

web依赖&project reactor依赖

项目启动类:

再定义一个传统的service,为模拟真实环境请求,service下的方法请求耗时100ms:

模拟耗时100ms

最后我们写三个接口,每个接口采用不同的方式:

  1. 使用自定义调度器的方式
  2. 使用缓存的弹性调度器
  3. 传统的SpringMVC方式

代码如下图所示:

三种接口开发方式

ab压测

我们先对上面说的三个接口进行压测,为避免网络环境影响,我们直接在服务器上使用ab进行压力测试。

压测分三组,每组压测这三个接口,每个接口发起10w请求,每组用户数分别为200、500、1000,从而查看不同用户数请求下的响应结果。

第一组

压测结果:

10w请求数 200用户

可以看见传统的SpringMVC方式已经有阻塞了,最长的一次请求1107ms,但是整体性能基本一致,因为200个线程刚好是tomcat的线程池最大默认数。

第二组

ab -n100000 -c500 http://127.0.0.1:8080/hello1?id=1
ab -n100000 -c500 http://127.0.0.1:8080/hello2?id=1
ab -n100000 -c500 http://127.0.0.1:8080/hello3?id=1

压测结果:

10w请求 500用户

500用户请求时候可以看到hello3接口的响应时间已经是hello1和hello2两个接口响应时间的2倍以上了,但是基于project reactor响应编程开发方式的响应时间依旧和200用户一致。

我们继续将用户数加到1000。

第三组

ab -n100000 -c1000 http://127.0.0.1:8080/hello1?id=1
ab -n100000 -c1000 http://127.0.0.1:8080/hello2?id=1
ab -n100000 -c1000 http://127.0.0.1:8080/hello3?id=1

压测结果:

10w请求 1000用户

我们发现基于project reactor开发的接口响应时间依旧坚挺,传统SpringMVC方式开发的接口90%响应时间已经高达500ms了。

大家可以发现hello1和hello2两个接口的实现方式其实是一致的,无非是自己定义一个Scheduler还是用reactor默认的Scheduler,如果大家点进去看源码其实是一个意思,所以在性能上一致保持一致也是合理的,本质上都是无所不在的线程池:

至此我们就完成了在tomcat容器下的两种不同方式的接口开发以及得到相应的性能压测数据。

netty容器下代码演示

将pom.xml中的spring-boot-starter-web依赖换为webflux依赖即可:

webflux依赖

还是刚刚那三个接口,启动项目可以看到控制台有如下日志输出:

代表我们这是一个基于Netty的web服务。

这里我们直接压10w请求,1000用户:

ab -n100000 -c1000 http://127.0.0.1:8080/hello1?id=1
ab -n100000 -c1000 http://127.0.0.1:8080/hello2?id=1
ab -n100000 -c1000 http://127.0.0.1:8080/hello3?id=1

压测结果:

netty下压测10w请求1000用户

再和tomcat下同一压测参数进行对比:

tomcat下压测10w请求1000用户

是不是发现netty的性能比tomcat更加优越?99%的请求在149ms即可完成。如果大家自己实操的话也会发现吞吐量也会较tomcat有大幅度的提升。

总结

我们始终都在不遗余力的追求如何开发一个高并发、低延迟的接口

通过本文实操以及linux服务器下长时间的压测,可以验证的是我们可以使用WebFlux来替代SpringMVC,从而获取更好的性能,更高的并发。如果你还和我一样,对WebFlux还一知半解,那么从今天起开始学习起来吧。

相关文章:

Spring Boot 2 快速教程:WebFlux优缺点及性能分析(四)

WebFlux优缺点 【来源DeepSeek】 Spring WebFlux 是 Spring 框架提供的响应式编程模型,旨在支持非阻塞、异步和高并发的应用场景。其优缺点如下: 优点 高并发与低资源消耗 非阻塞 I/O:基于事件循环模型(如 Netty)&am…...

自定义多功能输入对话框:基于 Qt 打造灵活交互界面

一、引言 在使用 Qt 进行应用程序开发时,我们经常需要与用户进行交互,获取他们输入的各种信息。QInputDialog 是 Qt 提供的一个便捷工具,可用于简单的输入场景,但当需求变得复杂,需要支持更多类型的输入控件&#xff0…...

基于springboot河南省旅游管理系统

基于Spring Boot的河南省旅游管理系统是一种专为河南省旅游行业设计的信息管理系统,旨在整合和管理河南省的旅游资源信息,为游客提供准确、全面的旅游攻略和服务。以下是对该系统的详细介绍: 一、系统背景与意义 河南省作为中国的中部省份&…...

LabVIEW图像采集与应变场测量系统

开发了一种基于LabVIEW的图像采集与应变场测量系统,提供一种高精度、非接触式的测量技术,用于监测物体的全场位移和应变。系统整合了实时监控、数据记录和自动对焦等功能,适用于工程应用和科学研究。 项目背景 传统的位移和应变测量技术往往…...

CommonAPI学习笔记-2

一. 概述 ​ 这篇文章主要是想整理并且分析CommonAPI代码生成工具根据fidl和fdepl配置文件生成出来的代码的结构和作用。 二. fidl ​ 用户根据业务需求在fidl文件中定义业务服务接口的结构以及自定义数据类型,然后使用core生成工具传入fidl文件生成该fidl的核心…...

ISP代理与住宅代理的区别

代理充当用户和互联网之间的中介,在增强安全性、隐私和可访问性方面提供多种功能。在众多代理类型中,ISP和住宅代理脱颖而出,各自拥有不同的功能和应用程序。 一、ISP代理 ISP代理,俗称Internet服务提供商代理,通过其…...

[25] cuda 应用之 nppi 实现图像色彩调整

[25] cuda 应用之 nppi 实现图像色彩调整 在 NPPI(NVIDIA Performance Primitives)中,图像色彩调整通常包括以下几种操作: 亮度调整:增加或减少图像的亮度。对比度调整:增强或减弱图像的对比度。饱和度调整:增强或减弱图像的颜色饱和度。色调调整:改变图像的色调(通常…...

Java 大视界 -- Java 大数据在智慧文旅中的应用与体验优化(74)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...

PyTorch快速入门

Anaconda Anaconda 是一款面向科学计算的开源 Python 发行版本,它集成了众多科学计算所需的库、工具和环境管理系统,旨在简化包管理和部署,提升开发与研究效率。 核心组件: Conda:这是 Anaconda 自带的包和环境管理…...

100.7 AI量化面试题:如何利用新闻文本数据构建交易信号?

目录 0. 承前1. 解题思路1.1 数据处理维度1.2 分析模型维度1.3 信号构建维度 2. 新闻数据获取与预处理2.1 数据获取接口2.2 文本预处理 3. 情感分析与事件抽取3.1 情感分析模型3.2 事件抽取 4. 信号生成与优化4.1 信号构建4.2 信号优化 5. 策略实现与回测5.1 策略实现 6. 回答话…...

CF 465B.Inbox (100500)(Java实现)

题目分析 计算读取所有未读邮件所需的步数,其中1代表未读,0代表已读 思路分析 遍历邮件,如果当前是未读,那么所需步数1,如果下一封也是未读,不用管(遍历后会直接1),如果下一封是已读&#xff0…...

微信小程序获取openid和其他接口同时并发请求如何保证先获取到openid

在微信小程序中,如果你需要并发请求获取 openid 和其他接口的数据,并且希望确保先获取到 openid 之后再进行后续操作,可以考虑以下几种方法: 方法一:使用 Promise 链 1, 先请求 openid:使用 Promise 来请求 openid。 2, 在获取到 openid 后再请求其他接口。 function g…...

实现动态卡通笑脸的着色器实现

大家好!我是 [数擎 AI],一位热爱探索新技术的前端开发者,在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | A…...

DeepSeek R1 模型解读与微调

DeepSeek R1 模型是 DeepSeek 团队推出的一款重要的大语言模型,旨在通过强化学习提升大型语言模型的推理能力。 模型架构 DeepSeek-R1-Zero DeepSeek-R1-Zero 是 DeepSeek 团队推出的第一代推理模型,完全依靠强化学习(RL)训练&…...

YOLOv11实时目标检测 | 摄像头视频图片文件检测

在上篇文章中YOLO11环境部署 || 从检测到训练https://blog.csdn.net/2301_79442295/article/details/145414103#comments_36164492,我们详细探讨了YOLO11的部署以及推理训练,但是评论区的观众老爷就说了:“博主博主,你这个只能推理…...

Node.js学习指南

一、模块化规范 nodejs使用的模块化规范 叫做 common.js 规范: 每一个模块都有独立的作用域 代码在各自模块中执行 不会造成全局污染 每一个模块都是一个独立的文件(module对象) 模块可以被多次加载(module.exports 属性) 但是仅…...

2.5学习总结

今天看了二叉树&#xff0c;看的一脸懵&#xff0c;写了两道题 P4913&#xff1a;二叉树深度 #include <stdio.h> #include <stdlib.h> struct hly {int left;int right; }tree[1000005]; int hulingyun(int x) {if(x0)return 0;return 1max(hulingyun(tree[x].le…...

java进阶文章链接

java 泛型&#xff1a;java 泛型详解-绝对是对泛型方法讲解最详细的&#xff0c;没有之一 Java 泛型&#xff0c;你了解类型擦除吗&#xff1f; java 注解&#xff1a;深入理解Java注解类型 秒懂&#xff0c;Java 注解 &#xff08;Annotation&#xff09;你可以这样学 jav…...

vue2+vue3 HMCXY基础入门

vue2vue3 HMCXY基础入门 一、Vue2.x技术精讲1.Vue快速上手&#xff08;1&#xff09;Vue概念&#xff08;2&#xff09;创建实例&#xff08;3&#xff09;插值表达式&#xff08;4&#xff09;响应式特性&#xff08;5&#xff09;开发者工具 2.Vue指令二、Vue3.x技术精讲 一、…...

一次线程数超限导致的hive写入hbase作业失败分析

1.集群配置 操作系统:SuSe操作系统 集群节点:100台相同配置的服务器 单台:核心112Core,内存396G 2.问题现象 现象1:跑单个入库任务报错,批量提交任务后出现OOM异常 执行12个hivesql,将数据写入hbase.hbase入库有近一半的任务报错。 每次报错的任务不是同一个,hivesql…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...