性能测试接口测试CLI【免费下载链接】artilleryThe complete load testing platform. Everything you need for production-grade load tests. Serverless distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.js module.项目地址https://gitcode.com/gh_mirrors/ar/artillery点击查看免费下载Artillery 内置的 HTTP 引擎在每次请求后都会自动记录http.response_time、http.requests、http.codes.*等标准指标但业务级别的度量例如宠物创建请求数、某一服务端计时段落的耗时并不在默认采集范围内。本篇指南以仓库中的 examples/track-custom-metrics 示例为骨架讲解如何通过自定义 JS 处理器processor配合afterResponse钩子利用events事件总线发射自定义counter与histogram指标并将其与直方图一起输出到 Artillery 的测试报告。读完本文你将掌握自定义指标从定义 → 采集 → 聚合 → 报告呈现的完整链路。示例结构与运行流程examples/track-custom-metrics目录是一个完整可运行的闭环示例包含以下文件文件作用app.js被测 API 服务器Express提供POST /pets接口并输出Server-Timing响应头custom-metrics.ymlArtillery 测试脚本加载处理器并在场景级声明afterResponse钩子metrics.js自定义处理器发射pets_created计数器和pet_creation_latency直方图package.json服务器依赖清单express与server-timing运行链路分为两步安装并启动被测 API 服务器执行 Artillery 测试脚本让虚拟用户按arrivalRate持续向/pets发起 POST 请求每收到一个响应即触发afterResponse钩子收集自定义指标。第一步启动被测 API 服务器先安装服务器依赖npm install该命令会安装 package.json 中声明的两个依赖express^4.17.1提供 HTTP 服务server-timing^3.3.1中间件负责生成 W3C 规范的Server-Timing响应头。然后启动服务器node app.js服务启动后监听在http://localhost:3000/。查看 app.js 的源码可以看到被测接口的实现要点const express require(express); const serverTiming require(server-timing); const app express(); const port 3000; app.use(express.json()); app.use(serverTiming()); app.post(/pets, (req, res) { res.startTime(pets, Creating pet); setTimeout( () { res.endTime(pets); res.json({ species: req.body.species, name: req.body.name }); }, Math.ceil(Math.random() * 500) ); }); app.listen(port, () { console.log(App listening at http://localhost:${port}); });这个接口刻意在 0~500ms 之间随机延迟后返回从而为后续的延迟直方图提供有分布的样本数据。关键点在于res.startTime(pets, Creating pet)开始记录名为pets的计时段res.endTime(pets)结束计时server-timing中间件据此在响应头中输出类似pets;durxxx的Server-Timing头。这份 Server-Timing 头正是处理器解析延迟数据的来源也是服务端计时与负载测试打通的巧妙设计。第二步理解测试脚本 custom-metrics.yml测试脚本 custom-metrics.yml 是整个示例的核心配置config: target: http://localhost:3000 processor: ./metrics.js phases: - arrivalRate: 25 duration: 60 scenarios: - afterResponse: trackPets flow: - post: url: /pets json: species: pony name: Tiki逐项拆解其含义config.target所有请求的基准地址场景中url: /pets会拼接为http://localhost:3000/petsconfig.processor声明处理器文件路径。Artillery 会加载该文件并将其导出的函数挂到config.processor对象上供场景钩子按函数名引用config.phases负载阶段定义。arrivalRate: 25表示每秒新启动 25 个虚拟用户duration: 60表示持续 60 秒合计约 1500 个虚拟用户向服务器发起请求scenarios[0].afterResponse: trackPets场景级响应后钩子在 HTTP 引擎每收到一个响应后调用名为trackPets的处理器函数scenarios[0].flow虚拟用户执行的请求序列这里仅包含一个POST /pets请求携带 JSON 请求体。从引擎源码看afterResponse既可以在场景级声明如本例也支持在单个请求步骤内通过requestParams.afterResponse声明。在 packages/artillery/lib/core/engine_http.ts 中两者会被合并后按顺序逐个调用const functionNames _.concat( opts?.afterResponse || [], params.afterResponse || [] ); async.eachSeries( functionNames, function iteratee(functionName: string, next) { const fn template(functionName, context); let processFunc config.processor?.[fn]; // ...逐个执行 }, // ... );值得注意的细节处理器通过函数名字符串从config.processor中按名查找因此metrics.js必须module.exports导出名为trackPets的函数若在处理器中找不到对应函数引擎会打印WARNING: custom function name could not be found并以空回调兜底不会中断测试见 engine_http.ts 的 TODO 分支处理器既支持同步函数(req, res, context, events, done)风格也支持返回 Promise 的异步函数引擎会根据processFunc.constructor.name判断调用方式engine_http.ts引擎只有在场景或请求中声明了capture、match或afterResponse时才会进入响应处理流程needToProcessResponse判断见 engine_http.ts这也解释了为什么自定义指标采集必须显式声明钩子。第三步编写自定义指标处理器 metrics.js处理器 metrics.js 是本示例的业务指标采集器module.exports { trackPets }; function trackPets(_req, res, _context, events, done) { // After every response, increment the pets_created counter by 1. events.emit(counter, pets_created, 1); // Parse the server-timing header and look for the pets metric, // and add it to pet_creation_latency histogram. const latency parseServerTimingLatency( res.headers[server-timing], pets ); events.emit(histogram, pet_creation_latency, latency); return done(); } function parseServerTimingLatency(header, timingMetricName) { const serverTimings header.split(,); for (const timing of serverTimings) { const timingDetails timing.split(;); if (timingDetails[0] timingMetricName) { return parseFloat(timingDetails[1].split()[1]); } } }处理器函数签名afterResponse钩子的处理器统一接收五个参数参数含义requestParams本次请求的参数URL、请求体等本例未使用故命名为_reqres响应对象包含headers、body、statusCode等字段。引擎在调用钩子前会主动把响应体挂到res.body见 engine_http.tscontext虚拟用户上下文包含vars变量表可读写跨请求共享的变量events场景事件发射器自定义指标通过它上报done回调函数处理器完成工作后必须调用以继续场景流程计数器events.emit(counter, ...)events.emit(counter, pets_created, 1);每次响应到达即累加 1用于统计测试期间总共创建了多少只宠物。这个自定义计数器与引擎内置计数器走的是同一条数据通路——在 packages/artillery/lib/core/runner.ts 中运行器监听了scenarioEvents上的counter事件并转发给指标聚合器runState.scenarioEvents new EventEmitter(); runState.scenarioEvents.on(counter, (name: string, value: number) { metrics.counter(name, value); });引擎内部对http.requests、http.responses、http.codes.*的统计也是通过同样的ee.emit(counter, ...)完成的见 engine_http.ts这说明自定义计数器与内置指标共享同一套聚合、取样与报告机制。直方图events.emit(histogram, ...)events.emit(histogram, pet_creation_latency, latency);把从响应头解析出的延迟值加入pet_creation_latency直方图。运行器将histogram事件路由到metrics.summary(name, value)见 runner.ts因此该指标在报告中会以直方图形态呈现——包含 min / max / mean / median / p95 / p99 等统计值与内置的http.response_time展示方式一致。引擎自身对响应时间、DNS、TCP、TLS 等分段耗时的记录同样走ee.emit(histogram, ...)通道见 engine_http.ts自定义直方图可以与之并列查看。解析 Server-Timing 头parseServerTimingLatency是一个纯函数负责把形如pets;dur123.45的Server-Timing响应头解析为数值。实现逻辑按,分割得到多个计时段若存在多个对每段再按;分割timingDetails[0]是计时段名称找到与目标名称pets匹配的段从timingDetails[1]形如dur123.45中取出后的数值并parseFloat。这一做法把服务端框架如 Express 的server-timing中间件暴露的计时信息桥接进负载测试指标是打通前后端可观测性的一个轻量范例。实际项目中你也可以从其他响应头、响应体或 HTTP 状态码中提取任意业务数据作为自定义指标来源。第四步运行测试并查看自定义指标被测服务器运行在http://localhost:3000/后在示例目录下执行artillery run custom-metrics.yml测试按arrivalRate: 25 / duration: 60的相位运行 60 秒。期间每个响应都会触发trackPets累计发射约 1500 次counter事件和等量的histogram事件。报告中的呈现方式在报告输出端控制台报告器会分别渲染三类自定义指标见 packages/artillery/lib/console-reporter.ts计数器pets_created走printCounters输出形如pets_created: 1500的单值行直方图pet_creation_latency走printSummaries输出min / max / mean / median / p95 / p99六项统计值console-reporter.ts。可以预期报告会同时出现内置指标http.codes.200、http.requests、http.response_time等自定义指标pets_created计数器与pet_creation_latency直方图。其中pet_creation_latency的分布应大致对应服务端 0~500ms 的随机延迟可用于验证服务端处理耗时与客户端观测延迟的一致性。关于采样与汇总Artillery 的指标系统以固定间隔对计数器/直方图做采样聚合相关数据模型见 packages/artillery/lib/core/ssms.ts 中customStats字段的设计。自定义指标与内置指标一样参与这一机制因此它们也会出现在 JSON 报告-o输出与 HTML 报告中方便后续用artillery report或外部工具做离线分析。自定义指标机制的扩展视角除本示例展示的两类事件外运行器还为自定义处理器暴露了更多事件通道见 runner.ts事件语义对应聚合方式counter计数累加metrics.counter(name, value)histogram数值分布统计metrics.summary(name, value)summary同上直方图别名metrics.summary(name, value)rate每秒速率metrics.rate(name)customStat旧版自定义统计已标记弃用metrics.summary(stat.stat, stat.value)error上报错误码metrics.counter(errors.code, 1)这意味着同一个处理器函数不仅能做计数 直方图还能上报每秒速率如每秒宠物创建量或错误统计。自定义指标与内置指标共用同一报告管线因此无论是控制台实时输出、JSON 导出还是 HTML 报告自定义指标都能无缝纳入。小结通过examples/track-custom-metrics这个完整示例可以看到 Artillery 自定义指标的标准套路被测端接口输出可供解析的度量载体本例为Server-Timing响应头配置端在测试脚本的config.processor中加载处理器文件并在场景级声明afterResponse钩子采集端处理器函数内用events.emit(counter | histogram, ...)上报业务指标呈现端运行器把事件路由进指标聚合器控制台与报告中以计数器和直方图形式呈现与内置指标并列可读。这套机制适用于任何标准指标覆盖不到、但业务上需要度量的场景例如自定义业务计数、服务端分段耗时、外部依赖延迟等是 Artillery HTTP 压测中做精细化可观测性的基础能力。赞分享性能测试接口测试CLI【免费下载链接】artilleryThe complete load testing platform. Everything you need for production-grade load tests. Serverless distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.js module.项目地址https://gitcode.com/gh_mirrors/ar/artillery点击查看免费下载相关推荐shadow-rs 最佳实践10 个提升 Rust 项目质量的实用技巧shadow rs 最佳实践10 个提升 Rust 项目质量的实用技巧 shadow rs 是一款在编译期自动收集构建信息的 Rust 工具它能把 Git开发工具localtunnel请求延迟优化CDN与边缘计算全指南localtunnel请求延迟优化CDN与边缘计算全指南 引言解决本地开发的远程访问痛点 你是否遇到过使用localtunnel进行远程测试时因请求延迟过网络开发工具后端MediaPipe 数据集实战3 步把散图变成能训练的完整数据集MediaPipe 数据集实战3 步把散图变成能训练的完整数据集 装标注工具装到一半报错、导出的 XML 和代码对不上、格式转换折腾一下午——这些事我都被坑过人工智能机器学习计算机视觉多模态本地部署上一篇MOTR完全指南基于Transformer的端到端多目标跟踪框架详解下一篇EMO项目用户界面设计原则打造直观的动态肖像生成体验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?