跳到正文

HTTP 请求的负载测试 ​

HTTP 请求 节点可以按每秒请求数的负载模式多次发送其请求,同时发出多个,并测量返回的结果:延迟百分位数、错误、达到的速率。阈值决定步骤是否通过,对比 则把这些数字与之前某次运行的数字并排列出。

负载是节点的一项设置,而不是单独的节点:实验的其余部分(模拟器、损伤中继、其他分支)照常在它周围运行。

让请求承受负载 ​

  1. 选择一个 HTTP 请求 节点,填写其请求。
  2. 在其属性中,开启 在负载下发送。
  3. 选择 负载模式 并填写相应的数值。下方的图表 速率随时间变化 会绘出速率,并显示合计多少个请求、持续多少秒。
  4. 设置 并发数,即同时可以有多少个请求在途。
  5. 添加或修改 阈值。
  6. 运行实验。

负载的初始设置是 斜坡:在 30,000 ms 内从每秒 0 个请求增加到 100 个,并发 32 个,带两个阈值:p95 < 500 ms 和 错误 < 1%。

负载取代重复和重试。开启负载会关闭这两项,同时带有负载和其中任一项的节点会被拒绝(node.load_alone):失败的请求只计数,不会重试。只有 HTTP 请求可以在负载下运行(node.load_unsupported)。

请求只读取一次。其模板在步骤开始时解析,因此负载中的每个请求都完全相同:{{counter}} 和 {{uuid}} 对所有请求都取同一个值。参见模板。

整个负载只用一个客户端。当 在请求之间保留 Cookie 开启时,这些请求共用本次运行的 Cookie 存储,并共用同一份 Digest 认证状态,因此一次质询即可用于所有请求。每个请求都使用节点自己的超时。

检查器只收到样本:每 100 ms 最多一次交互,因此负载不会淹没 检查器。

负载模式 ​

负载模式设置速率随时间的变化
恒定速率(请求/s)、时长(ms)始终保持该速率
斜坡起始(请求/s)、结束(请求/s)、时长(ms)从一个速率沿直线变化到另一个速率
阶梯起始(请求/s)、步长(请求/s)、每级(ms)、阶数先是起始速率,此后每一级增加一个步长,每一级持续相同的时间
尖峰基础(请求/s)、峰值(请求/s)、尖峰起点(ms)、尖峰时长(ms)、时长(ms)基础速率,从给定时刻起保持一段时间的峰值,然后回到基础速率
随机速率(请求/s)、时长(ms)随机到达,平均为该速率

切换模式时会保留能够沿用的设置:持续多久,以及达到的最高速率。

限制 ​

设置范围
恒定 和 随机 的 速率(请求/s),峰值(请求/s)0.1–100,000 请求/s
起始(请求/s)、结束(请求/s)、基础(请求/s)0–100,000 请求/s
阶梯 的每一级,包括最后一级0–100,000 请求/s;步长可以为负
时长(ms)、每级(ms)100–300,000 ms
阶数1–100,且所有级合计最多 300,000 ms
尖峰长于 0 ms,并在时长结束前结束
并发数1–512
阈值最多 16 个,每个值为大于或等于 0 的数字

合计没有任何请求的负载模式会被拒绝(load.nothing_planned)。速率范围与 HTTP 突发负载相同。

负载模式最长可以持续一整次运行的时长,即 300 s——但运行的时间限制会计入每个步骤,因此请为实验的其余部分留出时间。

请求数 ​

负载模式的请求数就是其速率随时间的累计:

负载模式请求数
恒定,100/s,持续 1000 ms100
斜坡,0 → 100/s,持续 2000 ms100
阶梯,从 10/s 起每级增加 10/s,3 级,每级 1000 ms60(10 + 20 + 30)
尖峰,10/s,从 1000 ms 起以 100/s 持续 500 ms,总计 2000 ms65
随机,200/s,持续 10,000 ms平均 2000

调度 ​

第 n 个请求在负载模式的累计数达到 n 的时刻到期,第一个请求立即发出。每个时刻都从负载开始时算起,因此一次延迟的唤醒绝不会推迟其后的请求,负载模式所描述的速率就是所要求的速率。

随机 从本次运行的种子中随机抽取到达间隔:相同的种子给出相同的时刻,因此随机负载也可以精确重现。参见种子。

错过的请求。同时在途的请求最多为 并发数 个。当它们全都还在等待应答时,下一个请求会等待空闲的并发槽。如果它的发出时间会比预定时刻晚 50 ms 以上,就不会延迟发送:它会被跳过并计为错过,期间到期的其他所有请求也是如此,负载随后从第一个仍然准时的请求继续。错过的请求很多,说明服务器或 并发数 跟不上负载模式。

运行期间 ​

时间线每秒一次将该步骤显示为 负载中,并给出已过的秒数、已发送的请求数、最近一秒的速率、目前为止的 p95 以及失败的请求数。停止 会立即结束负载,并放弃在途的请求;另一个分支中的失败会在一秒内结束负载。

测量内容 ​

最后一个应答之后,步骤就有了测量结果,保存在其最后一个时间线事件和运行报告中:

测量项内容
planned负载模式合计的请求数(随机:平均值)
sent已得到应答或已失败的请求
ok以 2xx 状态应答的请求
failed任何其他状态,或根本没有应答
missed在所有并发槽都忙时到期而被跳过的请求
rps每秒发送的请求数:sent ÷ 负载模式的时长;如果最后一个请求发出得更晚,则 ÷ 到最后一个请求发出为止的时间
error_ratefailed 占 sent 的百分比
min, mean, max最快、平均和最慢的请求,ms
p50, p90, p95, p9950%、90%、95% 和 99% 的请求不超过的延迟,ms
received_bytes收到的正文字节总数
statuses按状态(200、503)统计的请求数,没有状态时按原因(timeout、refused、reset …)统计
seconds负载模式的每一秒:发送的请求数、失败的请求数及其平均延迟
histogram按延迟统计的请求数:不超过 1、2、5、10、20、50、100、200、500、1000、2000、5000、10,000 ms,以及更慢

请求的延迟从发送它开始,到读完整个应答为止;失败的请求按其失败所用的时间计算。百分位数从宽度为 1% 的对数分桶中读取,无论负载运行多久,与真实值的误差都在 0.5% 以内。

阈值 ​

阈值是由 指标、比较 和 值 组成的一行;阈值 用于添加一个阈值。

指标单位
p50、p90、p95、p99ms
平均、最慢ms
错误占已发送请求的 %
速率实际达到的每秒请求数
错过请求数

比较 为 <、≤、>、≥ 之一。几个常见的例子:

指标比较值步骤失败的条件
p95<300每二十个请求中有一个或更多用时 300 ms 或更长
错误<11% 或更多的请求失败
速率≥180服务器无法每秒处理 180 个请求
错过≤0哪怕只有一个请求不得不被跳过

在文件中,阈值写作 { "metric": "p95_ms", "op": "lt", "value": 300 };指标有 p50_ms、p90_ms、p95_ms、p99_ms、mean_ms、max_ms、error_rate、rps 和 missed,比较方式有 lt、le、gt 和 ge。

阈值在最后一个应答之后按顺序读取。步骤会在第一个不满足的阈值处失败(load.threshold),其消息给出该阈值和测得的值,运行也随之失败。没有阈值时,无论测得什么,负载都会通过。如果另一个分支的失败提前结束了负载,运行的失败就归于那个失败,而不是某个阈值。

结果 ​

步骤通过时,时间线会给出汇总:请求数、速率、p95 和失败比例。选中该节点,其属性会显示 上次运行的负载:

  • 每个阈值,✓ 满足 或 ✕ 未满足,附带测得的值;
  • 已发送、请求/s、错误 及其比例、错过;
  • p50、p90、p95、p99、平均、最大;
  • 每秒:每一秒的请求,失败的以红色显示,平均延迟以折线显示;
  • 延迟:多少请求用了多长时间;
  • 各个状态和原因,以及各自的计数。

命令行会输出同样的数字和每个阈值的判定结果;参见 signallab run。

对比两次运行 ​

  1. 运行实验两次或更多次。
  2. 在时间线中按 对比。有运行保存了报告后它就会出现,运行进行中时不可用。
  3. 最近一次运行作为 之后,前一次作为 之前;两个列表都可以选择其他运行。

列表中包含此实验(按名称识别)的运行,取自数据文件夹中的报告,最新的在最前,最多 50 个:每个都带有日期和时间、结束方式及其种子。如果命令行使用了同一个数据文件夹,命令行的运行也会在其中。重命名实验会开始新的历史记录。

对于每个负载步骤(按节点匹配),一个表格会显示每个指标的 之前 值、之后 值和 变化,以单位和百分比表示。朝不利方向变化 5% 或更多(更慢、更多错误、更多错过的请求、更低的速率)属于性能退化,以红色显示;从无到有也算。表格下方是每个阈值在两次运行中的判定结果。只有其中一次运行包含的负载步骤会标记为 仅之前 或 仅之后,不显示变化。没有负载步骤的运行显示 这些运行中没有负载步骤。

在脚本中,experiment_runs 列出运行,experiment_compare 按报告的文件名对比两次运行;signallab mcp 为 AI 助手提供同样的功能(MCP)。

负载之后的检查 ​

负载本身不会留下响应:它只被测量,不被检查。负载之后的检查或 提取值,需要在每条路径上都有一个不带负载的请求位于其前,否则实验无法运行(graph.needs_http)。要检查负载下 API 的某一次应答,请在负载之后放一个普通的 HTTP 请求,或将其放在旁边的并行分支中。

在负载下的节点上,立即发送 只发送一次其请求。