Web Frameworks Benchmark 仓库全解析:三层 YAML 配置、基准测试契约与 zrk 封闭回路压测方法论
性能测试开发工具后端【免费下载链接】web-frameworksWhich is the fastest web framework?项目地址https://gitcode.com/gh_mirrors/we/web-frameworks点击查看免费下载本文基于开源仓库 web-frameworks 的官方 README 及其配套源码系统讲解这套社区维护、可复现的后端 Web 框架基准测试体系的完整运作方式从统一的 HTTP 路由契约、三层 YAML 配置生成机制到本地运行与自定义压测参数再到负载模型与结果有效性判定。读完本文你将掌握如何在本仓库中构建、校验并收集任意框架的基准数据理解每个指标背后的测量模型并能正确解读排行榜上的数字。[!IMPORTANT] 需要先明确一个边界本仓库执行的是最小化 HTTP 吞吐与延迟测试不能替代对生产应用的性能剖析。框架特性、可维护性、生态、安全性、数据库访问以及你的真实业务负载同样决定选型结果。项目定位从 HTTP 微基准到决策支持指南从成熟的重量级全栈框架到小巧的 HTTP 路由器本仓库将数百个实现统一约束在同一个微小的 API后面并在相互隔离的容器中运行它们见 README.md。今天它让 Web 技术栈性能中可测量、可复现、可讨论的部分变得容易长期目标则是形成一份基于证据的选型指南帮助企业选择后端框架——而不是仅仅输出一个宣布唯一赢家的排行榜。Roadmap 中的几个方向也印证了这一演进见 README.md 的 Roadmap 章节采用更现代的负载生成器优化各框架实现在公有云上搭建真实基础设施检查每个框架的 HTTP 合规性构建框架决策模型并发布面向企业的实用业务指南。其中决策模型的呈现方式借鉴了象限式市场分析的清晰性但评估模型专为后端框架设计且以透明、可复现的证据为支撑项目保持独立与 Gartner 无关联或背书关系。基准测试契约所有实现必须通过的三个路由仓库里每个实现都必须在3000端口监听并返回完全一致的响应见 README.md 的 Benchmark contract 章节方法路由预期状态码预期响应体GET/2xx空GET/user/:id2xxid路径参数POST/user2xx空在正式压测之前共享的 RSpec 契约 .spec/route_spec.rb 会先验证这三条路由。以GET /user/0为例契约要求响应为Net::HTTPSuccess且响应体等于0context GET : /user/0 do subject(:response) { http.request(Net::HTTP::Get.new(/user/0)) } it returns successfully do expect(response).to be_a(Net::HTTPSuccess) end it returns the expected param do expect(response.body.to_s).to eq(0) end end契约的连接目标由 .spec/spec_helper.rb 构造它读取LANGUAGE、FRAMEWORK、ENGINE环境变量然后从language/framework/ip-engine.txt中取出容器 IP用Net::HTTP连接3000端口——这也解释了为什么生成的 Makefile 的test目标是ENGINE#{variant} LANGUAGE#{language} FRAMEWORK#{framework} bundle exec rspec .spec见 .tasks/config.rake 的commands_for。以javascript/fastify的实现为例app.mjs 用最少的代码满足契约GET /user/:id直接回显request.params.idPOST /user与GET /返回空响应而 cluster.mjs 通过 Node 的cluster模块按availableParallelism()派生工作进程让多 worker 共享 3000 端口。三层 YAML 配置一次生成 Dockerfile 与 Makefile基准配置由三个 YAML 层级叠加生成见 README.mdconfig.yaml # provider 与全局设置 language/config.yaml # 语言镜像、运行时与引擎设置 language/framework/config.yaml # 框架版本、文件、启动命令与覆盖项其底层实现位于 .tasks/config.rake 的get_config_from读取../../config.yaml全局、../config.yaml语言层与config.yaml框架层后通过 .tasks/helpers.rb 中定义的Hash#recursive_merge做递归合并——键值冲突时框架层覆盖语言层、语言层覆盖全局层因此每个框架可以用最小配置声明自己的差异。随后config.rake的config任务会遍历所有*/*/config.yaml用 Mustache 模板渲染生成.Dockerfile.engine与.MakefileMANIFESTS 常量中的container: .Dockerfile、build: .Makefile。看一个具体实例。全局 config.yaml 定义了 provider 层——dockerprovider 的build、metadata、clean、unbuild命令模板以及digitaloceanprovider 的云上构建流程语言层 javascript/config.yaml 声明了node: { version: 26-slim }以及node/bun/deno/uwebsockets等引擎各自的environment、bootstrap与启动command如node cluster.mjs框架层 javascript/fastify/config.yaml 则只需三行framework: website: fastify.dev version: 5.12运行时版本、启动命令、文件列表、环境变量都从上层配置继承。默认生成的基准运行对GET /持续15 秒禁用 keep-alive、应用延迟修正并记录一份ohaJSON 报告并发度与路由均可配置。采集字段包括每秒请求数、总接收数据量、运行时长以及p50 / p75 / p90 / p99延迟百分位见 README.md。结果数据与解读原则最新发布结果可在 Web Frameworks Benchmark 仪表盘查看每次结果都应放在其框架版本、运行时/服务器变体、并发度、基准修订版与硬件的语境中阅读见 README.md 的 Results 章节。为了公平解读只比较同一基准修订版、同一台机器产出的运行结果关注选定的运行时/服务器变体而不只是框架名例如 fastify 在 node 与 bun 引擎下差异巨大将微小差异视为噪声直到重复出现不要把这个最小 API 测试的结果外推到数据库密集或完整应用负载。发布的数据集沉淀在仓库根目录的 data.json 与 data.min.json 中以metrics数组形式记录了每个框架在64/256/512等并发级别的total_requests_per_s、各百分位延迟、total_bytes_received、duration_ms、socket_read_errors等字段level字段即并发级别framework_id关联具体框架。本地运行一个实现从依赖安装到结果收集前置要求GitDockerRuby 与 BundlerCI 当前使用 Ruby 4见 .github/workflows/ci.yml 中的ruby-version: 4.0.7PATH上的zrkjq安装 Ruby 依赖并生成 Dockerfile 与 Makefilegit clone https://github.com/the-benchmarker/web-frameworks.git cd web-frameworks bundle install bundle exec rake config然后挑选一个实现——例如javascript/fastify——使用它生成的 Makefilemake -f javascript/fastify/.Makefile build make -f javascript/fastify/.Makefile test make -f javascript/fastify/.Makefile warmup mkdir -p javascript/fastify/.results/10 make -f javascript/fastify/.Makefile collect make -f javascript/fastify/.Makefile unbuild结果写入language/framework/.results/目录下生成的目标还包括用于移除框架容器的clean。这里有一个值得注意的细节在收集结果之前必须为每个配置的并发级别创建对应的.results/concurrency目录批处理运行器会自动为其预定义级别创建。如果你想用默认并发之外的值就需要手动mkdir -p见 README.md 与 run.sh 中mkdir -p .../.results/{64,256,512}的做法。warmup目标也有讲究它直接以满速zrk -c 50 -d 5s预热因为 JIT 运行时需要真实负载才能达到稳态——zrk默认的 1000 req/s 步进负载不足以完成预热见 .tasks/config.rake 中commands[:warmup]的注释。批处理运行器run.sh 是跑全部、跑一种语言或跑一个框架的批处理入口它按参数范围用find定位config.yaml无参数跑全仓库一个路径段跑一种语言两个路径段跑单个框架并在开始前校验zrk版本——ZRK_MIN2.4.0因为--closed需要 2.2.0而 2.4.x 是验证过的版本版本过旧会在数百个框架逐个构建之前就快速失败而不是几小时后得到一堆空的.results。每个框架依次执行 build → sleep 60 → test失败则跳过并打印Failure in ...→ warmup → collect → unbuild。自定义一次运行生成器接受逗号分隔的并发级别与路由。在生成 Makefile 时设置它们见 README.md 的 Customize a run 章节CONCURRENCIES64,256,512 \ ROUTESGET:/,GET:/user/42,POST:/user \ bundle exec rake config然后照常执行同一个collect目标。路由条目使用METHOD:/path形式config.rake中默认值为CONCURRENCIES10、ROUTESGET:/每个路由的结果按uri.tr(/, _)命名如_user_42.json。还有三个变量控制压测工作在哪里执行THREADS设置 zrk 使用的压测线程数默认取LOAD_CPUS中的核数未设置时取全部宿主机核心。zrk 自己默认的 2 个线程远不足以压满一个快速的服务器见 .tasks/config.rake 中threads ENV.fetch(THREADS) { cpuset_size(load_cpus) || Etc.nprocessors }。SERVER_CPUS与LOAD_CPUS接受如0-3、4-15的 cpuset 规格分别通过--cpuset-cpus把框架容器钉在SERVER_CPUS上、通过taskset -c把负载生成器钉在LOAD_CPUS上让两者占用不相交的核互不抢占.tasks/helpers.rb 的load_generator_prefix负责生成taskset前缀并在taskset不可用时降级为不钉核。LATENCY_RATE为每个路由增加一次固定速率的第二轮压测。闭回路轮次报告的是饱和状态下的吞吐与延迟这一轮则报告在定义负载下的延迟并带协调遗漏coordinated-omission修正。LATENCY_RATE50%取该框架自身闭回路速率的一半保证每个框架都在自己能承受的负载内被测LATENCY_RATE20000则对所有人使用同一绝对速率。结果写入route_latency.json导入为latency_at_rate_*指标与头条速率分开。它会让收集时间翻倍默认关闭。固定速率的取值逻辑在 .tasks/latency_rate.rb 中它从同路由的闭回路结果读取achieved_rate百分比按floor(achieved * N / 100)折算若闭回路运行失败导致速率缺失则回退到 1000 req/s 并在 stderr 说明原因。其他可调变量还包括DURATION默认15s传给 zrk 的-d参数与--timeout 8s的请求超时见 .tasks/config.rake。[!CAUTION] 一次完整基准会消耗大量 CPU、内存、时间、网络带宽与容器存储。请从单个实现开始并把负载生成器与你关心的服务隔离开见 README.md。一次运行到底测量了什么排行榜上的每个数字都来自同一种负载模型因此在比较两个数字之前先弄清这个模型是什么见 README.md 的 What a run measures 章节。keep-alive 连接上的闭回路closed loop。zrk --closed -c N打开 N 条连接每条连接在上一个响应到达的瞬间就发送下一个请求唯一的调节旋钮就是 N。total_requests_per_s是整轮运行的requests / duration延迟列则是该并发下的单请求服务时间。闭回路下饱和的服务器会在 N 条连接内排队请求所以 c512 时的延迟主要是排队延迟——这在相同 N 下跨框架是可比的、符合预期的。定义负载下的延迟是独立的可选轮次LATENCY_RATE固定速率的开回路带协调遗漏修正。它回答的是另一个问题永远不会改变头条速率。生成器按压满服务器来配置规模。zrk 运行THREADS个压测线程LOAD_CPUS中的每个核或全部宿主机核SERVER_CPUS/LOAD_CPUS让两者占用不相交的核。要压满一个快速服务器大致需要每 1 个服务器核配 3 个生成器核。每次运行都会声明自己是否有效。saturation.json记录服务器消耗其分配 CPU 的比例以及保持忙碌的核数。超过 75% 说明服务器是瓶颈这个数字属于框架低于 50% 说明瓶颈在别处——通常是生成器或网络路径——那么这个数字描述的是瓶颈本身而非框架。单线程服务器钉满多核机器中的一个核时占比会很低但确实被该核绑定要把占比与核数结合起来读。bundle exec rake db:check_saturation会列出需要怀疑的运行。饱和度探针的实现位于 .tasks/saturation.rb它在收集轮次前后各读取一次容器 cgroup 的累计 CPU 计数器cgroup v2 的cpu.stat的usage_useccgroup v1 的cpuacct.usage算出的saturation按 ≥0.75 / ≥0.50 划分为server-bound/mixed/server-idle三个判定。容器可用核数从容器内部读取优先cpu.max配额其次nproc避免用宿主机核数做分母把忙碌的服务器误判为空闲。每次collect运行都会在.results/concurrency/saturation.json写入该判定。为什么数字会移动负载模型的三个时期方法在 2026 年发生过变更不同修订版的结果不可直接比较——这正是 Results 章节中同一基准修订版的含义见 README.md时期生成器与负载模型头条速率的意义直到 2026-08oha闭回路每请求新建连接接受 请求成本由连接建立主导2026-09-02 至 2026-09-15zrkkeep-alive 上线性攀升至 500k req/s攀升的最后一个 1 秒窗口延迟是调度积压本修订版起zrk --closedkeep-alive规模确定且钉核的生成器有效性探针N 条连接下整轮持续速率附带该 N 下的延迟注意config.rake中针对被替换的开回路攀升模型的注释指出zrk 2.4.2会把攀升的achieved_rate报告为最后一个--interval的数值因此头条速率只是 15 秒中的 1 秒且每个延迟数字都是从预定发送时间算起的调度积压真实 p50 约 1ms 的服务器会显示数百毫秒——这正是改版的原因。添加或更新一个框架欢迎各种形式的贡献新框架与变体、依赖更新、正确性修复、文档与基准改进见 README.md 的 Add or update a framework 章节。一个典型实现位于language/framework/包含一个config.yaml描述其版本、网站、文件、启动命令与引擎变体满足共享路由契约的最小应用可复现容器构建所需的依赖清单或 lockfile。验证一次贡献bundle exec rake config make -f language/framework/.Makefile build make -f language/framework/.Makefile test make -f language/framework/.Makefile unbuild提交 PR 前请阅读 CONTRIBUTING.md 并遵守 CODE_OF_CONDUCT.md如果你就是所添加框架的维护者请在 PR 中注明——这有助于评审者评估惯用配置与调优。CI 采用变更实现矩阵.github/workflows/ci.yml 在 PR 时通过git diff --name-only找出变更文件bundle exec rake ci:languages映射到受影响语言后复用 .github/workflows/ci-language.yml 逐语言跑契约测试。依赖更新通过开源的 Renovate CLI 每天自动进行在仓库添加名为RENOVATE_TOKEN的 Actions secret使用专用机器人账号的 token而非waghanza经典 PAT 需要repo与workflow权限才能同时更新依赖与 GitHub Actions。Renovate 扫描仓库内所有受支持的清单文件包括 npm、Cargo、Composer、Bundler、Go、Maven、Gradle、Python、Dart、Swift 与 Mix另有一条自定义规则覆盖 GitHub 托管的 Crystal shards。config.yaml中带renovate:注释的版本会随依赖清单一起更新DUB、Nimble 与 Julia 的包清单因 Renovate 没有内建管理器仍需手动更新。仓库地图路径用途language/framework/框架实现与配置.spec/共享 HTTP 正确性契约.tasks/配置、CI、收集、云与数据库任务.github/workflows/ci.yml变更实现 CI 矩阵config.yaml全局 provider 与执行模板data.json/data.min.json已发布基准数据集run.sh批量运行器全部 / 一种语言 / 一个框架项目以 MIT 协议发布见 LICENSE由社区维护、可复现地比较后端 Web 框架。理解上述契约、配置层与负载模型之后你就能在本仓库中复现任一框架的基准结果并对其中的每个数字做出有依据的解读。赞分享性能测试开发工具后端【免费下载链接】web-frameworksWhich is the fastest web framework?项目地址https://gitcode.com/gh_mirrors/we/web-frameworks点击查看免费下载相关推荐C-Fast-FoundationStereo实战用PyTorch实现立体视觉disparity估计的完整指南C Fast FoundationStereo实战用PyTorch实现立体视觉disparity估计的完整指南 想要实现实时立体视觉disparity估计吗人工智能计算机视觉基础模型Awesome Go的性能测试基准测试与压力测试方法论Awesome Go的性能测试基准测试与压力测试方法论 引言为什么性能测试如此重要 在当今高速发展的互联网时代Go语言以其卓越的并发性能和简洁的语法设计文档知识库Ferret 测试与性能基准策略契约分层、验证顺序与基准回归防控指南Ferret 测试与性能基准策略契约分层、验证顺序与基准回归防控指南 本篇指南以 Ferret声明式数据自动化语言及其 Go 运行时维护者工程文档中的 T网页爬虫后端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考