2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家
第一张表格让我感到不安:在我的机器上,使用实验室的真实工作负载,嵌入式 GlassFish 似乎胜过了 Spring Boot。如果当时就发布,这篇文章会更有冲击力,但在方法论上却显得薄弱。我暂停了进度,并补充了缺失的部分:为所有环境统一支持的 Java 开发工具包(JDK)、独立的预热阶段、更长的测量时间窗口、固定的堆内存大小、明确的连接池设置,以及使用 pg_stat_statements 来归因数据库开销。至此,结论发生了变化。
本文并非旨在判定谁“永远获胜”。它讲述的是当基准测试变得公平时,我的解读如何随之改变。以及为何如果我今天在一个已经熟悉 Spring 的团队中启动一个全新项目,我仍然会选择 Spring Boot;但如果我在一个使用 Payara/Jakarta 的组织中,我会尝试 Payara Micro;而如果存在寻求轻量级可执行文件的 Jakarta 代码,嵌入式 GlassFish 就会进入讨论范围。
为何进行此实验
- 我带着一个易于复述的观点而来:“Spring Boot 始终是显而易见的选择”。我希望用证据而非直觉来挑战这一观点。
- 我对现代 Jakarta EE 感兴趣,且不怀旧。我想看看在当今而非 2012 年,它是否仍有真正的生存空间。
- 我避免了简单的“Hello World”示例。构建了一个小型但贴近现实的、重度依赖数据库的应用程序接口(API),包含读取、写入、聚合和混合负载。
- 编辑目标很简单:依据可辩护的测量数据做出决策,而非依赖坊间传闻。
我实现的系统
实验室的业务领域是货运智能(shipment-intelligence),同一套 API 在三种运行时环境中提供服务:Spring Boot、嵌入式 GlassFish 和 Payara Micro。
- PostgreSQL 数据库,带有大型确定性数据集(10 万条货运记录)。
- 通过追踪 ID(trackingId)读取追踪信息。
- 运营摘要(路线和体量)。
- 分页显示延迟的货运记录。
- 向数据库真实摄入事件。
- 健康检查/就绪检查。
- 使用 k6 作为负载生成器,采用共享场景。
- 测量常驻集大小(RSS)、垃圾回收(GC)日志、运行时的标准输出/标准错误(stdout/stderr),以及使用 pg_stat_statements 来理解数据库成本。
此处不展示代码。对于本文而言,重要的是这三个版本实现了相同的 HTTP 契约,指向同一个数据库,并使用相同的 k6 场景。
随着方法论的改进,结论如何变化
本实验室的叙事转折可以通过两张图表来解释:第二阶段和第四阶段。前者代表了快速发布的诱惑,后者则标志着实验变得可辩护。
第二阶段表格(现实操作基准测试,每个运行时运行 3 次)
| 运行时 | 中位数 p50 | 中位数 p95 | 中位数 p99 | 中位数吞吐量 |
|---|---|---|---|---|
| 嵌入式 GlassFish | 4.66 毫秒 | 58.77 毫秒 | 111.85 毫秒 | 86.46 请求/秒 |
| Payara Micro | 16.32 毫秒 | 135.76 毫秒 | 238.61 毫秒 | 71.17 请求/秒 |
| Spring Boot | 36.59 毫秒 | 340.50 毫秒 | 594.74 毫秒 | 53.36 请求/秒 |
对第二阶段的诚实解读:如果就此止步,容易得出的标题便是“GlassFish 回归了”。但缺失的因素太多:没有使用 pg_stat_statements,未记录每次运行的常驻集大小(RSS),样本量过短,未分离预热阶段,Java 开发工具包(JDK)版本未统一,且连接池并未全部以相同方式声明。这为继续研究提供了良好基础,但不足以终结话题。
第三阶段增加了因果分析和复杂性(虚拟用户数分别为 10/25/50/100,每种组合运行三次,数据库归因,前后常驻集大小对比,垃圾回收日志)。在高虚拟用户数下,GlassFish 在尾部延迟方面依然表现强劲,Payara 在吞吐量上展开竞争,而 Spring Boot 则保持较低的常驻集大小。但出现了一个关键警告:在某些运行中,Payara 提示 Java 开发工具包(JDK)不受支持。因此需要一个更公平的阶段。
第四阶段:基准测试的公正性
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。