Tomcat 配合虚拟线程,一种新的编程体验

2023-12-05

Java 21 在今年早些时候的 9 月 19 日就正式发布,并开始正式引入虚拟线程,但是作为 Java 开发生态中老大哥 Spring 并没有立即跟进,而是在等待了两个月后的 11 月 29 日,伴随着 Spring Boot 3.2 版本的发布,在这个版本中也终于是引入了对虚拟线程的支持。

虚拟线程的引入标志着 Java 在现代编程世界中对编写高吞吐量、高并发应用程序提供了更加完美的支持。

本文我就带着大家一起深入了解一波 Tomcat 配合虚拟线程会带来怎样的效果以及虚拟线程对以后使用 Java 开发高吞吐量、高并发应用程序时所带来的改变。

本文大纲如下,

Tomcat 使用虚拟线程

启用虚拟线程

在 Spring Boot 3.2 中,使用 Tomcat 作为 web 容器时,启用虚拟线程只需要将 spring.threads.virtual.enabled 属性设置为 true。

这样 Spinrg Boot 在启动 Tomcat 容器时会使用一个虚拟线程执行器来代表原有的平台线程池。

注意这里是虚拟线程执行器,不是虚拟线程池哦。

源码解析

在 Spring Boot 3.2 版本以前,Tomcat 默认的线程池使用的就是 Java 提供的 ThreadPoolExecutor 线程池,在 3.2 版本以后,Spring Boot 修改了创建线程池的方法如下所以,

Tomcat使用何种执行器

Tomcat使用何种执行器

是否使用虚拟线程执行器

是否使用虚拟线程执行器

可以看到 Tomcat 会先判断是否启用了虚拟线程,启用了的话就直接创建一个虚拟线程执行器 VirtualThreadExecutor

VirtualThreadExecutor 类是 Tomcat 为了使用虚拟线程作为执行器而新增的。他的内部代码中针对每个请求任务都是依赖 Jre21Compat 类处理的。

Jre21Compat 类则是 Tomcat 为了兼容 Java21 版本虚拟线程新增的一个兼容类。这个类利用反射方法来调用 Thread.ofVirtual().start(() -> {}) 方法,以便进行任务处理,代码截图如下,

VirtualThreadExecutor类源码

VirtualThreadExecutor类源码

Jre21Compat类源码

Jre21Compat类源码

虽然以上代码可以启用 Tomcat 的虚拟线程支持。但是在 Spring Boot 中其实不是这样设置的。还记得上文提到的在 Spring Boot 3.2 中,使用 Tomcat 作为 web 容器时,启用虚拟线程只需要将 spring.threads.virtual.enabled 属性设置为 true 吗?

Spring Boot 3.2 中是通过 tomcatVirtualThreadsProtocolHandlerCustomizer 方法来兼容虚拟线程启用逻辑的, @ConditionalOnThreading(Threading.VIRTUAL) 条件用判断 spring.threads.virtual.enabled 属性是否启用。代码如下,

根据spring.threads.virtual.enabled属性决定是否启用虚拟线程

根据spring.threads.virtual.enabled属性决定是否启用虚拟线程

读取spring.threads.virtual.enabled属性

读取spring.threads.virtual.enabled属性

到这里其实本文所需要讲的涉及源码的部分就全部讲完了。可以看到 Tomcat 引入虚拟线程并不复杂,引入后不在需要维护线程池,减轻了执行器的复杂度。

虚拟线程带来的改变

不知道大家注意到源码中一个改变没有,就是在 Spring Boot 3.2 中,启用了虚拟线程后,Tomcat 默认使用的虚拟线程执行器不在需要池化。

也就是说,在 Spring Boot 3.2 以后的版本里,我们不在需要设置 server.tomcat.threads.max 以及 server.tomcat.threads.min-spare 两个属性以控制 Tomcat 线程池的大小了,因为它压根没有使用平台线程池。

对于 Tomcat 来说,引入虚拟线程,不必在为线程池的维护而费心,还能减轻编程的复杂度。

虚拟线程由 JVM 平台负责进行调度,它是廉价且轻量级的,Tomcat 可以使用 “每个请求一个线程” 模型,而不必担心实际需要多少个线程。

就算请求任务在虚拟线程中调用阻塞 I/O 操作,导致运行时虚拟线程被挂起阻塞,但是只要挂起结束后该虚拟线程就可以恢复。

使用了虚拟线程后,程序员使用普通的阻塞 API,也可以让程序对硬件的利用达到近乎完美水平,以此提供高水平的并发性,从而实现高吞吐量。

可以说,虚拟线程的引入,以后程序员就算是使用 Java 中阻塞 API 也可以开发出高性能、高吞吐量的应用程序。

jmter 实测

在本文中,我还将给各位展示一波 newbeepro 项目升级到 Spring Boot 3.2 后启用虚拟线程所带来的性能提升。

测试服务器

  • 主机名称 VM-16-5-centos

  • 发行版本 centos-7.9.2009

  • 内核版本 3.10.0-1160.88.1.el7.x86_64

  • 系统类型 x86_64

  • 系统配置:2 核 4 G 5M 带宽

测试平台配置

测试平台配置

测试项目

newbee-mall-pro 是 newbee-mall 商城的 pro 版本实现了推荐算法、商品秒杀、优惠卷使用,滑块验证码,支付宝支付,中文分词检索等高级功能。

项目地址:https://github.com/wayn111/newbee-mall-pro

测试方法

使用 newbee-mall-pro 作为测试项目将启用虚拟线程以及未启用虚拟线程的两次设置部署到测试服务器上。

启动容器:amazoncorretto:21.0.1

启动参数: java -jar -Xms1024m -Xmx1024m /opt/newbeemall/newbee-mall.jar

部署后测试地址:http://62.234.206.94/newbeemall/index

测试接口为秒杀接口:/newbeemall/seckill/2/c81e728d9d4c2f636f067f89cc14862c/executionFour

压测设置:启用 2000 个线程,每个线程循环执行 30 秒左右。一共测试五轮,先预热 JVM 后,取吞吐量最大值。

测试数据

启用虚拟线程

压测结果如下,

可以看到 CPU 占用达到百分之 142,内存占用达到百分之 35 的情况下,压测吞吐量最大可以达到 1731。

不启用虚拟线程

考虑到有 2000 个线程进行压测,所以将 Tomcat 线程池的最大线程数也设置到 2000,如下图,

压测结果如下,

可以看到 CPU 占用达到百分之 170,内存占用达到百分之 35 的情况下,压测吞吐量可以达到 1492。


OK,到这里我们可以看到在 Spring Boot 3.2 版本中,使用了虚拟线程的 Tomcat 对比不用虚拟线程时,吞吐量提升差不多有 20%。

在更高并发的测试中,这个差距会越来越明显。因为 Tomcat 使用的平台线程过多时,上下文切换开销会越来越大,而且虚拟线程比平台线程占用更少的内存,一个虚拟线程只占用几 kb 到几十 kb 内存。可以轻松创建上万虚拟线程,降低资源占用同时提高并发。

最后聊两句

虚拟线程带给了现代程序员新的编程体验,使用阻塞编程也能开发出高性能应用程序,而避免了异步模型的编程复杂度,随着更多的框架接入虚拟线程,相信虚拟线程会在未来大放异彩。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tomcat 配合虚拟线程,一种新的编程体验 的相关文章

随机推荐

  • 京东商品详情接口在电商行业中的重要性及实时数据获取实现

    一 引言 随着电子商务的快速发展 商品信息的准确性和实时性对于电商行业的运营至关重要 京东作为中国最大的电商平台之一 其商品详情接口在电商行业中扮演着重要的角色 本文将深入探讨京东商品详情接口的重要性 并介绍如何通过API实现实时数据获取
  • 城市化人群隔离悖论

    城市是人群大规模聚集的过程 表面上似乎会提高人与人之间相互接触和交往的效率 但不可思议的是 美国学者的研究发现 城市越大 人和人之间相互隔离越严重 这显然是违背直觉的现象 反直觉往往意味着新发现 就给这种现象命名为城市化人群隔离悖论吧 这是
  • 未来已来,AI与情报分析,是黑暗或光明?

    这篇文章有点像一个实验 在乔治城大学 Georgetown University 举行的 负责任的人工智能和情报 Responsible AI and Intelligence 会议上 ChatGPT被要求撰写一篇文章 陈述关于我将如何评估
  • 外卖小程序需要多大云服务器?

    外卖小程序是一种基于互联网技术实现的餐饮电商平台 具有实时配送 快速响应和跨地区订餐等特点 为保证外卖小程序在高并发和业务繁忙的情况下能够稳定运行 需要具备一定的云服务器配置 具体也有考虑公司业务规模大小 用户量 原文地址 外卖小程序需要多
  • 服务器2g内存个人使用可以吗?

    对于个人日常使用而言 云服务器2G内存是足够的 一般来说 对于普通用户而言 使用云服务器主要是用来搭建网站 存储文件和数据备份等基本操作 虽然这些操作看似比较简单 但是实际上还是需要一定的计算资源才能完成的 原文地址 服务器2g个人使用可以
  • 淘宝商品详情接口在电商运营中的应用实例

    一 背景 某电商企业A在运营过程中 发现手动更新商品信息效率低下 且容易出现信息不一致的情况 为了解决这个问题 企业A决定采用淘宝商品详情接口 实现商品信息的自动获取和更新 二 目标 通过集成淘宝商品详情接口 企业A希望实现以下目标 自动获
  • Latex公式中矩阵的方括号和圆括号表示方法

    一 背景 在使用Latex写论文时 不可避免的涉及到矩阵公式 有的期刊要求矩阵用方括号 有的期刊要求矩阵用圆括号 因此 特记录一下Latex源码在两种表示方法上的区别 以及数组和方程组的扩展 二 矩阵的方括号表示 首先所有的矩阵肯定都是在标
  • Python机器学习、深度学习入门丨气象常用科学计算库、气象海洋常用可视化库、爬虫和气象海洋数据、气象海洋常用插值方法、EOF统计分析、WRF模式后处理等

    目录 专题一 Python软件的安装及入门 专题二 气象常用科学计算库 专题三 气象海洋常用可视化库 专题四 爬虫和气象海洋数据 专题五 气象海洋常用插值方法 专题六 机器学习基础理论和实操 专题七 机器学习的应用实例 专题八 深度学习基础
  • 糟了,数据库崩了,又好像没崩

    前言 2023 年某一天周末 新手程序员小明因为领导安排的一个活来到公司加班 小明三下五除二 按照领导要求写了一个跑批的数据落库任务在测试环境执行 突然间公司停电了 小明大惊 糟了 MySQL 还在跑任务 会不会因为突然断电 导致数据库崩了
  • Spring IOC—基于XML配置和管理Bean 万字详解(通俗易懂)

    目录 一 前言 二 通过类型来获取Bean 0 总述 重要 1 基本介绍 2 应用实例 三 通过指定构造器为Bean注入属性 1 基本介绍 2 应用实例 四 通过p命名空间为Bean注入属性 1 基本介绍 2 应用实例 五 通过ref引用实
  • 搜狐CEO张朝阳:长期被动刷手机人就废了

    大家好 我是老洪 刚看到一则关于搜狐CEO张朝阳谈论关于使用手机问题的资讯 颇有感触 聊两句 在12月2日下午 一场特别的讲座在西安交通大学引起了热议 这场讲座的主讲人 正是搜狐公司的首席执行官张朝阳 他不仅是一位优秀的企业家 更是一位热爱
  • 腾讯云购买服务器多大合适?

    对于个人日常建站来说 购买多大的服务器合适需要根据实际需求进行考虑 一般个人用户的话2GB或者是4GB内存接基本够用了 原文地址 腾讯云购买服务器多大合适 轻量云Cloud 首先 需要考虑的是网站的访问量 如果只是一个简单的个人网站 每天只
  • 2023最新网络安全Web Hacking 101笔记,祝你更好的学习网络安全!

    在计算机技术如日中天的今天 Web安全问题也接踵而来 但Web安全却 入门简单精通难 涉及技术非常多且广 学习阻力很大 为此今天分享一份94页的 Web Hacking 101 笔记 包含Web安全知识 例如HTML注入 XSS CSRF
  • python爬虫数据采集

    近几年来 python的热度一直特别火 大学期间 也进行了一番深入学习 毕业后也曾试图把python作为自己的职业方向 虽然没有如愿成为一名python工程师 但掌握了python 也让我现如今的工作开展和职业发展更加得心应手 这篇文章主要
  • 美国国防部采办中的ChatGPT:高级语言模型的机遇和风险

    随着人工智能的不断进步 像 ChatGPT 这样的大型语言模型有可能彻底改变国防采购和合同签订的方式 由于语言模型能够生成类似人类的文本 因此可以自动完成采购中的许多重复而耗时的任务 如文件准备 研究和沟通 与任何新技术一样 国防工业采用大
  • MySQL 8.0 压缩版安装教程

    1 下载mysql压缩包 2 解压文件 我这里把压缩包解压到E盘的根目录 3 配置系统环境变量 为了让Windows系统可以识别我们这里后面会用到的MySQL命令 需要给当前系统添加环境变量 我的电脑 右键 gt 属性 gt 高级系统设置
  • 轻量应用服务器小程序部署可以吗?

    轻量应用服务器是指提供了一定的并发能力 等功能的云服务器 它可以实现对网站 小程序提供高效 安全的技术支持 而小程序则是一种新的开放能力 不仅具有出色的使用体验 还可以在微信内被便捷地获取 为用户提供便利的服务 原文地址 轻量应用服务器小程
  • 浅析Hotspot的经典7种垃圾收集器原理特点与组合搭配

    浅析Hotspot的经典7种垃圾收集器原理特点与组合搭配 HotSpot共有7种垃圾收集器 3个新生代垃圾收集器 3个老年代垃圾收集器 以及G1 一共构成7种可供选择的垃圾收集器组合 新生代与老年代垃圾收集器之间形成6种组合 每个新生代垃圾
  • WebGL笔记:图形缩放的原理和实现

    缩放 1 原理 缩放可以理解为对向量长度的改变 或者对向量坐标分量的同步缩放 如下图 比如 让向量OA 收缩到点B的位置 也就是从OA变成OB 缩放了一半 2 公式 已知 点A的位置是 ax ay az 点A基于原点內缩了一半 求 点A內缩
  • Tomcat 配合虚拟线程,一种新的编程体验

    Java 21 在今年早些时候的 9 月 19 日就正式发布 并开始正式引入虚拟线程 但是作为 Java 开发生态中老大哥 Spring 并没有立即跟进 而是在等待了两个月后的 11 月 29 日 伴随着 Spring Boot 3 2 版