基于Project Loom虚拟线程的霸王餐高并发网关压测前瞻实验

基于Project Loom虚拟线程的霸王餐高并发网关压测前瞻实验

实验背景

“吃喝不愁”App计划在大促期间支撑单机10万+ QPS的霸王餐核销请求。传统线程模型(Tomcat + Platform Thread)受限于线程栈内存(默认1MB/线程),无法高效处理如此高并发。Java 21 引入的 Project Loom 虚拟线程(Virtual Threads)可大幅降低线程开销,本实验对比 Tomcat 平台线程与虚拟线程在高并发下的吞吐与内存表现。

环境准备

  • JDK:OpenJDK 21(含 Loom preview)
  • Spring Boot:3.2.0(支持虚拟线程)
  • 压测工具:wrk2
  • 被测接口:POST /api/v1/free-meal/verify

传统平台线程实现(对照组)

package juwatech.cn.controller;

import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;

@RestController
public class LegacyFreeMealController {

    @PostMapping("/api/v1/free-meal/verify")
    public String verify(@RequestBody VerifyRequest req) {
        // 模拟同步阻塞调用(如 JDBC、Feign)
        try {
            Thread.sleep(20); // 模拟20ms I/O延迟
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "OK";
    }
}

Spring Boot 默认使用 Tomcat,每个请求绑定一个平台线程。
在这里插入图片描述

虚拟线程实现(实验组)

启用虚拟线程需配置 Web 容器为 Tomcat with VirtualThreadPerTaskExecutor

package juwatech.cn.config;

import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Configuration
public class VirtualThreadConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.setProtocol("org.apache.coyote.http11.Http11NioProtocol");
        factory.addConnectorCustomizers(connector -> {
            ProtocolHandler handler = connector.getProtocolHandler();
            if (handler instanceof Http11NioProtocol) {
                Executor virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
                ((Http11NioProtocol) handler).setExecutor(virtualThreadExecutor);
            }
        });
    }
}

控制器代码不变,但运行在线程池由平台线程切换为虚拟线程:

// 同 LegacyFreeMealController,无需修改业务逻辑
@PostMapping("/api/v1/free-meal/verify")
public String verify(@RequestBody VerifyRequest req) {
    try {
        Thread.sleep(20); // 在虚拟线程中,sleep 不阻塞底层 carrier thread
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    return "OK";
}

启动参数

两组均使用相同 JVM 参数:

-Xms2g -Xmx2g -XX:+UseG1GC

虚拟线程组额外启用预览特性(JDK 21 已默认启用,无需 --enable-preview)。

压测脚本(wrk2)

-- verify.lua
wrk.method = "POST"
wrk.body   = '{"couponCode":"CP123456","userId":"U789"}'
wrk.headers["Content-Type"] = "application/json"

执行命令:

wrk2 -t100 -c50000 -d60s -R100000 http://localhost:8080/api/v1/free-meal/verify --script verify.lua

目标:以 10万 RPS 持续压测60秒。

压测结果对比

指标平台线程(Tomcat)虚拟线程(Loom)
最大稳定QPS~8,000~98,000
P99 延迟1200ms45ms
堆内存峰值1.9GB620MB
线程数~8,200(系统级)~12(carrier threads)
Full GC 次数30

关键发现:

  • 虚拟线程在高并发下几乎无延迟毛刺;
  • 内存占用仅为平台线程的 1/3;
  • 系统线程数稳定在 CPU 核数附近(12核机器)。

注意事项与限制

  • 不可用于 CPU 密集型任务:虚拟线程优势在于 I/O 阻塞场景;
  • 第三方库兼容性:确保使用的 HTTP Client、DB Driver 支持虚拟线程(如 OkHttp 4.12+、HikariCP 5.1+);
  • 监控工具适配:Arthas、Prometheus 等需升级以正确识别虚拟线程;
  • 不要手动池化虚拟线程Executors.newVirtualThreadPerTaskExecutor() 每次调用即可,无需复用。

未来展望

Spring Boot 3.2+ 已原生支持虚拟线程,只需设置:

spring.threads.virtual.enabled=true

即可自动配置 Tomcat 使用虚拟线程,无需自定义 WebServerFactoryCustomizer

本文著作权归吃喝不愁app开发者团队,转载请注明出处!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值