Spring Boot 3.2 于 2023 年 11 月大张旗鼓地发布,标志着 Java 开发领域的一个关键时刻。这一突破性的版本引入了一系列革命性的功能,包括:

  • 虚拟线程:利用 Project Loom 的虚拟线程释放可扩展性,从而减少资源消耗并增强并发性。
  • Native Image支持:通过Native Image编译制作速度极快的应用程序,减少启动时间并优化资源利用率。
  • JVM 检查点:利用 CRaC 项目的 JVM 检查点机制实现应用程序的快速重启,无需冗长的重新初始化。
  • RestClient:采用新的 RestClient 接口的功能方法,简化 HTTP 交互并简化代码。
  • Spring for Apache Pulsar:利用 Apache Pulsar 的强大功能实现强大的消息传递功能,无缝集成到您的 Spring Boot 应用程序中。

其中,虚拟线程是最近 Java 版本中引入的最具变革性的特性之一。正如官方文件所述:虚拟线程是轻量级线程,可减少编写、维护和调试高吞吐量并发应用程序的工作量。线程是可以调度的最小处理单元。它与其他此类单位同时运行,并且在很大程度上独立于其他此类单元运行。它是 java.lang.Thread 的一个实例。有两种线程:平台线程和虚拟线程。平台线程是作为操作系统 (OS) 线程的瘦包装器实现的。平台线程在其底层操作系统线程上运行 Java 代码,平台线程在平台线程的整个生命周期内捕获其操作系统线程。因此,可用平台线程数限制为操作系统线程数。与平台线程一样,虚拟线程也是 java.lang.Thread 的实例。但是,虚拟线程不绑定到特定的操作系统线程。虚拟线程仍在操作系统线程上运行代码。但是,当在虚拟线程中运行的代码调用阻塞 I/O 操作时,Java 运行时会挂起虚拟线程,直到它可以恢复为止。与挂起的虚拟线程关联的操作系统线程现在可以自由地对其他虚拟线程执行操作。虚拟线程适用于运行大部分时间被阻塞的任务,通常等待 I/O 操作完成。但是,它们不适用于长时间运行的 CPU 密集型操作。

虽然人们普遍认为虚拟线程在 I/O 密集型方案中表现出色,但它们在 CPU 密集型任务中的性能仍然是一个问号。本系列文章深入探讨了虚拟线程在各种用例中的潜在优势,从基本的“hello world”到静态文件服务(I/O 密集型)、QR 码生成(CPU 密集型)和多部分/表单数据处理(混合工作负载)等实际应用。

在本系列的开头文章中,我们已经了解了虚拟线程与物理线程相比在最简单(且不切实际)的 hello world 情况下的性能。物理线程和虚拟线程之间几乎没有任何性能或资源使用差异。在本文中,我们将更加“实用”,并针对静态文件服务器情况进行比较。这绝对是一个常见且“真实世界”的案例。让我们看看这次我们发现了什么。

如果大家正在做Spring Boot 2.3升级Spring 3.2,这里顺手给大家推荐Spring Boot 2.x 到 3.2 的升级指南

测试环境

所有测试均在配备 16G RAM、8 个物理内核和 4 个效率内核的 MacBook Pro M2 上执行。测试工具是 Bombardier,它是更快的 HTTP 负载测试器之一(用 Go 编写)。

软件版本为:

  • Java v21.0.1
  • Spring Boot 3.2.1

程序配置

除了主 Java 类之外,不需要编写任何 Java 文件,静态文件服务器只能通过配置就能发挥作用。

application.properties文件如下:

server.port=3000
spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=file:/Users/mayankc/Work/source/perfComparisons/static/

使用虚拟线程时,我们将通过添加以下行来启用它们:

spring.threads.virtual.enabled=true

pom.xml内容:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

测试数据

大小完全相同但数据不同的 100K 文件被放置在静态资源目录中。每个文件大小正好是 102400 字节。

文件的命名范围为 1 到 100000。

使用 Bombardier 的修改版本,为每次运行生成随机请求 URL: http://localhost:3000/static/<file-name>

应用场景

为了确保结果一致,每个测试在开始数据收集之前都会经历 5K 请求预热阶段。

然后,在不同范围的并发连接级别(50、100 和 300)中仔细记录测量结果,每个级别都承受 500 万个请求工作负载。

结果评估

除了简单地跟踪原始速度之外,我们还将采用详细的指标框架来捕获延迟分布(最小值、百分位数、最大值)和吞吐量(每秒请求数)。

CPU 和内存的资源使用情况监控将补充此分析,从而提供不同工作负载下系统性能的全面了解。

测试结果

结果以图表形式呈现如下:

总结

对静态文件服务的分析表明,物理线程在性能和资源效率方面略胜一筹(与我们的预期相反)。

不过,这种受 I/O 限制的场景可能并不是充分发挥虚拟线程潜力的理想场所。涉及数据库交互的任务可能会显示出更多令人信服的优势。也许负载不足以让虚拟线程发挥出最大的作用。为了找出答案,我们将在接下来的文章中介绍 URL短链(数据库驱动)、二维码生成(CPU受限)和混合工作负载场景(如表单数据处理),旨在揭示虚拟线程真正出类拔萃的案例。

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

用Spring Boot 3.2虚拟线程搭建静态文件服务器有多快?的更多相关文章

  1. spring boot / cloud (四) 自定义线程池以及异步处理@Async

    spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...

  2. Spring Boot 项目学习 (一) 项目搭建

    0 引言 本文主要记录借用Idea 开发环境下,搭建 Spring Boot 项目框架的过程. 1 系列文档目录 Spring Boot 项目学习 (一) 项目搭建 Spring Boot 项目学习 ...

  3. CentOS 6(64-bit) + Nginx搭建静态文件服务器

    Nginx搭建静态文件服务器 使用命令打开Nginx配置文件: sudo vim /etc/nginx/conf.d/default.conf 将配置改为: server { ...... ..... ...

  4. Ubuntu 14.04TLS Nginx搭建静态文件服务器

    Nginx搭建静态文件服务器 [官方教程]https://www.nginx.com/resources/admin-guide/serving-static-content/ 打开Nginx的配置文 ...

  5. 【ELK】5.spring boot日志集成ELK,搭建日志系统

    阅读前必看: ELK在docker下搭建步骤 spring boot集成es,CRUD操作完整版 ============================================== 本章集成 ...

  6. spring boot+mybatis+quartz项目的搭建完整版

    1. 利用spring boot提供的工具(http://start.spring.io/)自动生成一个标准的spring boot项目架构 2. 因为这里我们是搭建spring boot+mybat ...

  7. Spring Boot学习笔记---Spring Boot 基础及使用idea搭建项目

    最近一段时间一直在学习Spring Boot,刚进的一家公司也正好有用到这个技术.虽然一直在学习,但是还没有好好的总结,今天周末先简单总结一下基础知识,等有时间再慢慢学习总结吧. Spring Boo ...

  8. Spring Boot微服务框架的搭建

    (1)spring boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发 ...

  9. spring boot:使用多个线程池实现实现任务的线程池隔离(spring boot 2.3.2)

    一,为什么要使用多个线程池? 使用多个线程池,把相同的任务放到同一个线程池中,可以起到隔离的作用,避免有线程出错时影响到其他线程池,例如只有一个线程池时,有两种任务,下单,处理图片,如果线程池被处理图 ...

  10. spring boot:使用async异步线程池发送注册邮件(spring boot 2.3.1)

    一,为什么要使用async异步线程池? 1,在生产环境中,有一些需要延时处理的业务场景: 例如:发送电子邮件, 给手机发短信验证码 大数据量的查询统计 远程抓取数据等 这些场景占用时间较长,而用户又没 ...

随机推荐

  1. .netCore 图形验证码,非System.Drawing.Common

    netcore需要跨平台,说白点就是放在windows服务器要能用,放在linux服务器上也能用,甚至macos上. 很多时候需要使用到图形验证码,这就有问题了. 旧方案1.引入包 <Packa ...

  2. DRTREE - Dynamically-Rooted Tree 题解

    DRTREE - Dynamically-Rooted Tree 本题建议评蓝. 思路: 题目就是要对一颗不定根树求子树权值和. 这题不带修,如果带修难度会增加一点,就跟 遥远的国度 差不多. 首先分 ...

  3. 虹科案例 | 石油天然气行业CFD高性能计算解决方案

    公司简介 DNV GL 是全球领先的能源.石油和海事行业风险管理及资产绩效提升的软件供应商,主要为客户提供全面的风险管理和各类评估认证服务,认证涉及信息通信技术.汽车及航空天.食品与饮料.医疗等方面. ...

  4. 🎁平平无奇的 Docker 命令(日常流)

    Docker search docker search 命令用于在 Docker Hub 上搜索镜像,语法如下: docker search [OPTIONS] TERM 常用的选项包括: --fil ...

  5. 【matplotlib 实战】--雷达图

    雷达图(Radar Chart),也被称为蛛网图或星型图,是一种用于可视化多个变量之间关系的图表形式.雷达图是一种显示多变量数据的图形方法.通常从同一中心点开始等角度间隔地射出三个以上的轴,每个轴代表 ...

  6. sql删除进程

    使用一下语句杀掉进程 USE master go DECLARE @dbname VARCHAR(200) SET @dbname = 'xxxx' --要关闭进程的数据库名 DECLARE @sql ...

  7. 练习回—编译安装nginx

    练习回 练习,编译安装nginx. 1.yum安装依赖环境 yum -y install pcre-devel zlib-devel gcc gcc-c++ make 2."下载" ...

  8. HTTP 和 RPC 的区别

    一句话概括 RPC代表:Feign.Dubbo RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便. HTTP 代表:RestTemplate.HttpClient HTTP 主 ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (141)-- 算法导论12.1 1题

    一.用go语言,对于关键字集合(1,4,5,10,16,17,21),分别画出高度为 2.3.4.5和6的二又搜索树. 文心一言: 以下是用Go语言为给定的关键字集合(1, 4, 5, 10, 16, ...

  10. Python 哈希表的实现——字典

    哈喽大家好,我是咸鱼 接触过 Python 的小伙伴应该对[字典]这一数据类型都了解吧 虽然 Python 没有显式名称为"哈希表"的内置数据结构,但是字典是哈希表实现的数据结构 ...