1593 字
8 分钟

任务队列容量压测与验收边界

10 月 9 日,我补充了一个异步任务系统的容量压测。当天的 k6 smoke 完成了 42 个任务,未发现重复,观察到的执行槽占用峰值为 8;容量验收报告的结论却仍是 accepted=false。

这几个结果可以同时成立。任务跑通说明当前样本的执行链路可用,容量验收还要回答目标负载、等待时间和持续运行是否达标。本文根据当天记录事后整理,项目信息已匿名化,数字来自当时的报告。

先把提交请求和任务完成分开#

异步接口通常只负责创建任务。HTTP 返回成功后,任务还要经过排队、领取、执行和结果持久化。假如压测只统计提交接口的响应时间,得到的可能是一条很漂亮的曲线,队列却在继续增长。

这次需要观察的是完整任务链路:

提交请求 → 创建任务 → 排队 → Worker 领取 → 执行 → 记录终态

一次提交还可能触发多次查询或轮询。因此,我在读结果时先分清以下单位:

指标回答的问题
迭代启动速率压测脚本按什么速度开始执行场景
HTTP 请求数场景实际发出了多少个 HTTP 请求
任务创建数与完成数进入队列的任务最终去了哪里
执行槽占用同时有多少任务占用执行资源
排队时间与完成时间用户需要等多久

k6 的 constant-arrival-rate 配置的是每个时间单位启动多少次迭代。一轮迭代可以发一个请求,也可以提交任务后持续查询状态,不能把配置中的 rate 直接写成 HTTP RPS。k6 官方文档对此有明确说明。

同样,峰值占用 8 个执行槽,不等于 8 个虚拟用户,也不能换算成系统支持多少个真实用户。用户提交频率、单个任务耗时和外部服务配额都会影响队列。

smoke 报告里的三个数字#

当天报告记录如下:

观察项结果结论范围
完成任务数42这批 smoke 任务完成了
重复任务检查未发现重复本次样本没有观察到重复
执行槽占用峰值8本次运行观察到这一峰值
容量验收结果accepted=false报告未判定容量验收通过

这里的 accepted 是容量验收报告的判断字段。它不是某个业务提交接口返回的“请求是否接受”,也不表示那 42 个任务被拒绝。

smoke 的价值是先确认压测脚本、提交路径和任务终态对账能串起来。它还不足以替代目标容量测试。尤其是“未发现重复”,必须带着样本范围阅读:这批任务没有重复,不能据此承诺以后所有故障恢复和重试都不会重复。

这次压测实现已经合入代码基线,smoke 跑通,容量验收尚未通过。

结果对账比请求成功率多一步#

对任务系统而言,压测结束时间未必等于所有任务结束时间。如果仍有排队和执行中的任务,需要留出明确的收尾窗口,再检查每个提交记录对应的任务终态。

下面用简化伪代码演示任务终态对账:

for (const submission of submissions) {
const task = tasksById.get(submission.taskId);
if (!task) recordProblem("missing-task", submission.taskId);
else if (!terminalStates.has(task.status)) {
recordProblem("unfinished-task", task.id);
}
}

实际检查还要有业务定义:同一个幂等键对应几条任务,失败和取消是否属于允许的终态,重试是否产生重复执行或重复结果。仅用“提交次数减去完成次数”做差,解释不了失败、取消以及幂等重放。

持续容量测试还应观察队列是否越积越多。任务能够最终完成,但等待时间一直上升,说明测试期间的到达速度与处理速度已经失衡。只截取最后完成的任务,会把仍在等待的任务从统计中漏掉。

dropped_iterations 也要检查来源#

k6 的 dropped_iterations 统计没有启动的迭代。预分配的虚拟用户不足,或迭代变慢占住虚拟用户,都可能让计划中的迭代无法启动;它不能直接解释成“服务端丢了这些请求”。官方说明区分了压测配置不足与被测系统响应变慢等原因。

遇到这个指标,先确认计划负载是否真的施加到了系统,再结合请求耗时、迭代耗时和服务端队列曲线判断。否则可能把压测机的限制写成系统容量,也可能因为实际到达速率下降而误以为服务端已经稳定。

JSONB 大小边界是另一项检查#

当天还做了任务 JSONB 大小边界试验。它检查的是大输入在存储与校验路径上的行为,不能和吞吐测试合并成一个“通过”结论。

任务数量相同,载荷大小不同,数据库传输、序列化和内存占用也会不同。对允许用户提交结构化内容的接口,容量测试至少要记录载荷的规模;边界测试则应在隔离环境里检查临界值两侧的行为,以及被拒绝的输入有没有留下半条任务或不完整状态。

这次边界试验的结果尚不足以确定可复用的接口大小上限。应用对载荷的限制,需要结合校验、传输和运行资源确定,也不能等同于 PostgreSQL JSONB 的通用容量上限。

如果要继续做正式验收,我会先固定目标到达速率、任务类型与大小分布、持续时间、排队与完成时间门槛,再保存压测配置、代码版本和结果工件。这样下一轮才能回答“在什么条件下达到什么容量”。这次完成了 42 个任务的 smoke,容量报告没有通过验收。

任务队列容量压测与验收边界
https://blog.yangyus8.top/posts/task-queue-load-test-acceptance/
作者
杨与S8
发布于
2026-10-09
许可协议
CC BY-NC-SA 4.0

评论