跳转到内容

Spine 内部实验室测试 ​

2026-11-01, Spine 0.5.2, GOGC=400

我们在相同CPU和内存条件下比较了HTTP吞吐量、响应延迟和内存用量。这是Spine项目参考Web Frameworks Benchmark公开测量方法开展的自行测量。

比较结果

吞吐量在饱和负载下比较,延迟和内存在统一每秒2万请求的条件下比较。每个数值都是重新启动服务器后测得的3次结果的中位数。

饱和负载,256个并发连接

配置吞吐量 (req/s)p95 (ms)p99 (ms)
Spine163,559观测范围: 161,621–164,7393.1594.398
NestJS / Express93,977观测范围: 92,999–94,4333.5674.770
Spring MVC118,943观测范围: 117,960–121,5043.1193.891
FastAPI / Uvicorn50,173观测范围: 50,124–50,1905.4717.026

统一负载,每秒20,000请求

配置平均 (ms)p95 (ms)p99 (ms)观测内存用量 (MiB)
Spine0.1690.3991.062观测范围: 0.825–1.15441.8
NestJS / Express0.2100.5281.098观测范围: 0.956–1.509479.3
Spring MVC0.1990.5111.115观测范围: 1.093–1.235608.8
FastAPI / Uvicorn0.4111.0591.744观测范围: 1.563–1.814156.5

在统一每秒2万请求的条件下,Spine的平均响应时间为0.169ms,p95为0.399ms,p99为1.062ms。

固定目标负载下的响应延迟

本测试比较目标为每秒118,000次请求时的响应延迟。在用于吞吐量比较的独立饱和负载测试中,Spine为163,559 req/s,Spring MVC为118,943 req/s。

两种配置3次运行中记录的请求均返回HTTP 2xx,请求错误和超时均为0。

配置p95 (ms)p99 (ms)
Spine0.9442.739
Spring MVC60.92789.248
查看完成速率与统计依据

此完成速率记录于固定目标负载下,不代表最大吞吐量。完成速率为每次运行的成功响应数除以记录的耗时。不同运行的耗时可能不同,各列分别取3次独立服务器启动的中位数。完成速率不等于请求丢失率。

配置实际完成速率 (req/s)
Spine116,777
Spring MVC117,305

两种配置完成速率的中位数均来自第3次运行:Spine在15.142秒记录1,768,230次成功响应,Spring MVC在15.001秒记录1,759,690次。统计时长较长时,即使成功响应更多,每秒速率也可能较低。

每秒11.8万请求的条件接近Spring MVC的饱和吞吐量。p99的观测范围为Spine 2.707–2.931ms,Spring MVC 10.724–206.784ms。Spring MVC在3次测量中有1次未达到目标请求速率的98%,我们保留了该样本。

预计年度节省额

这是将实测CPU和内存用量代入vpsGOD公开套餐后得出的预测。请将以下费用与实际VM性能测量结果区分开来。

按每秒2万次请求计算的情景

使用Spine替代NestJS / Express时
₩73,440/ 年,预计节省
折合每月预计节省约₩6,120
3 vCPU / 6GB每年$80,一次性预付
使用Spine替代Spring MVC时
₩46,734/ 年,预计节省
折合每月预计节省约₩3,895
2 vCPU / 4GB每年$60,一次性预付
使用Spine替代FastAPI / Uvicorn时
₩126,851/ 年,预计节省
折合每月预计节省约₩10,571
4 vCPU / 8GB每年$120,一次性预付

根据vpsGOD年度预付费用的差额计算。每月节省额为年度差额除以12。比较对象也采用了较便宜的公开优惠套餐。

Spine的估算基于提供2 vCPU和256MB内存的套餐。该配置每年预付$25。

这是基于CPU性能和余量假设的预测。尚未在该VM上实测吞吐量和p99,额外流量和税费不计入其中。

查看配置和计算依据

计算采用的假设

假设单核性能为测量环境的50%,并预留20%的CPU余量。核心数按3次测量中最高的平均CPU用量计算。

将包含启动和预热阶段的内存占用观测最大值乘以1.25,再加上供轻量操作系统使用的128MiB。该值假设调整工作进程数量并直接运行预先构建的应用,并非实测的最低RAM需求。

在已确认且满足所需CPU和RAM的套餐中,选择年度基本费用最低的套餐。更大规格的优惠套餐若更便宜,也会用于比较对象。

优惠套餐按公平共享方式分配CPU。持续CPU分配比例未公开。尚未确认优惠套餐的地区、最终库存和续费价格。

套餐包含的流量为Spine 100GB、NestJS 2TB、Spring MVC 1TB和FastAPI 4TB。超额传输费用另计,所列费用并不表示可以整月持续处理每秒2万次请求。

若将CPU余量增加到30%,Spring MVC也需要3核。FastAPI需要5核,但已核查的公开列表中没有符合条件的单台VM,因此未计算该条件下的费用。

费用确认日期为2026-11-01。汇率为$1 = ₩1,335.27,根据2026-10-30欧洲中央银行的参考值计算。未使用首张账单折扣码。

预计年度节省额 = (比较套餐年费 − Spine套餐年费) × 汇率

测量环境和方法

主机ARM64,14核(10个性能核,4个能效核),RAM 24GB
参考频率约4.5GHz。测量期间未记录或固定实际运行频率。
运行环境Docker Desktop,Linux/arm64,HTTP/1.1 keep-alive,loopback
服务器资源上限所有实现均为3 vCPU、3GiB,无额外swap
负载生成器zrk 2.4.2,单独分配的9个CPU,内存1GiB
任务43字节JSON解析 → 字段验证 → JSON响应
重复测量每个实现重新启动服务器3次,每个测量窗口15秒,共30个样本
预热Spring MVC至少135秒,其余为45秒。最近3个窗口的吞吐量变异系数不超过5%
Spine设置GOGC=400,GOMAXPROCS=3,GOMEMLIMIT=2700MiB

运行版本

Spine0.5.2 · Echo 4.15.0 · Go 1.27.3
NestJS / ExpressNestJS 12.3.2 · Express 5.3.0 · Node.js 26.13.0 · 3 workers
Spring MVCSpring Boot 4.1.2 · Java 25.0.5 · Tomcat · virtual threads
FastAPI / UvicornFastAPI 0.162.0 · Uvicorn 0.54.0 · Python 3.15.2 · uvloop · httptools · 3 workers

选择这些代表性比较配置的原因

NestJS / ExpressAdapter

我们参考了未指定适配器时采用的默认ExpressAdapter配置,以及npm包下载规模。2026-10-01~30期间,@nestjs/platform-express的下载量为44,534,475次,@nestjs/platform-fastify为7,725,701次。下载量是包使用规模的参考指标,并非用户份额。

Spring MVC

我们参考了State of Spring 2024调查:1,464名受访者中,70%表示使用WebMVC。这是可多选的调查结果。测量使用了Tomcat和虚拟线程。

FastAPI / Uvicorn

我们选择了官方fastapi run命令默认使用的ASGI服务器Uvicorn,并使用3个工作进程、uvloop和httptools。

如何解读结果

  • JSON是测量时采用的共同任务。内存数值并非仅指JSON数据的大小,而是整个服务器容器的观测值,包含运行时、进程和工作进程。
  • 我们通过Spine的直接字段检查、NestJS的ValidationPipe/class-validator、Spring MVC的Jakarta Validation以及FastAPI的Pydantic,检查了相同的测试字段约束。
  • 固定请求速率下的延迟从计划发送时间开始计算,因此包含发送等待时间。饱和负载采用收到响应后再发送下一个请求的不同方式,应在相同负载条件下比较。
  • 结果来自单台主机上每次15秒、共3次的测量。DB、外部API、CORS、身份认证、TLS、逐请求DI服务调用和长时间运行稳定性不在测试范围内。
  • 内存按测量期间每隔1秒采集的memory.current计算各窗口中位数,再取3次运行的中位数。该值不表示最低所需RAM或进程RSS。

公开数据和验证

我们验证了30个正式测量样本、168项HTTP契约检查和30个HDR直方图。未出现请求错误或Docker OOMKilled标记。ZIP包含应用源码、测量代码、原始zrk JSON和直方图。

配置选择和测量标准的来源

← 返回主页面