性能门禁真实性修复 Delta¶
日期:2026-08-23 状态:实施中 范围:
qim-loadgen与隔离验收编排;不改变服务端业务语义、容量结论或发布目标。
1. 变更摘要¶
当前压测把客户端向 socket 成功写帧当作“实际到达率”,且各连接在认证完成后各自计时;这会在慢启动或 ACK/E2E 样本不足时给出无效的绿色结果。本 Delta 将性能窗口收敛为“全部客户端就绪后统一起跑、统一结束”,将发送、提交、SDK 应用和帧层投递分开记账。发布门禁仅以 SEND_ACK/SDK committed 的合并提交速率写入到达率工件,并明确检查 ACK 与端到端样本覆盖率。T-HEAVY 在测量前必须完成全量唯一会话分页核验;不能分页的服务会失败,不能以首页 201 条替代 5000 条。验收脚本将对五个服务实际抓取健康/指标端点,并为成功与失败都保留可审计工件。
2. 影响文件与职责¶
| 文件 | Delta 职责 |
|---|---|
crates/qim-loadgen/src/loadtest.rs |
输入校验、统一窗口、分离计数/速率、覆盖率门禁、原始摘要。 |
crates/qim-loadgen/src/sdk_lane.rs |
复用统一就绪/起跑信号,返回 SDK emitted/committed/applied。 |
crates/qim-loadgen/src/heavy.rs |
在测量前按协议分页读取并验证 N 个唯一会话;测量连接不复用核验连接。 |
crates/qim-loadgen/src/net.rs |
提供带 snapshot/cursor 的会话列表分页请求。 |
crates/qim-loadgen/src/main.rs |
拒绝尚未实现的 --loadtest --scenario 组合。 |
crates/qim-loadgen/src/stats.rs |
删除未接入、不能正确回填应用状态的死代码。 |
scripts/acceptance.sh |
smoke 外层路由、五服务 observability 断言、服务日志/环境/摘要工件。 |
scripts/integration/{lib,wait,run,assert-arrival-rate}.sh |
工件根目录、依赖日志、Outbox 实际 retention 配置/查询、以 committed rate 的 99% 阈值断言。 |
scripts/perf-test.sh |
说明工件目录和 committed-rate 门禁。 |
3. 新的门禁契约与阈值¶
- 所有帧层与 SDK 客户端完成认证/Online 后向协调器报就绪;协调器给出同一未来起跑时刻和同一结束时刻。未在 30 秒内全部就绪即失败。
- 记账口径:
emitted:客户端write_all成功,诊断用,不是实际到达率;committed:帧层收到与在途 request 对应的SEND_ACK,或 SDK 收到MessageStateChanged{Committed};发布到达率只取此项;sdk_applied:真实 SDK 去重后向上层发出的新消息;frame_delivered:帧层唯一PUSH_EVENTS,只用于帧层诊断。- 性能门禁阈值统一为 99%:
committed_rate / target_rate >= 0.99、帧层 ACK 覆盖率>= 99%、帧层 E2E 时延样本覆盖率>= 99%、SDK 泳道应用率>= 99%。99% 比旧实现的 95% 严格,同时允许调度抖动;工件必须同时保留原始分子、分母与各速率,禁止只引用比率。 - T-HEAVY 必须分页读到且仅读到
N个唯一目标会话、snapshot revision 恒定、每页 cursor 前进。协议/服务未实现分页时必须失败;这是阻止假绿,不代表服务端分页功能在本 Delta 中已实现。 - 首屏测量使用与核验不同的新连接,避免核验请求预热被测连接路径。
- smoke 结束前与 full 结束后,逐一请求 gateway/writer/mailbox/session/fanout 的
/healthz和/metrics。连接、HTTP、缺失任一五个qim_zero_invariant样本或任意样本非零,均失败。 - 隔离 Redpanda 在验收进程启动前创建或更新 Outbox topic 的真实
retention.ms,再从 broker 查询并断言它等于QIM_OUTBOX_RETENTION_MS。默认 retention 为 7 天(604800000 ms),fanout 恢复窗口默认 24 小时(86400000 ms)且必须严格小于实际 retention;两个值与 broker 查询原文写入工件。
4. 接口与集成点¶
- loadtest 与 SDK 泳道共享只包含“就绪通知 + 固定起止时间”的内部同步接口;不向 SDK 或服务端 crate 扩大公开协议。
net::Client增加会话列表分页方法,直接映射既有PullSessionListUp.snapshot_revision/page_cursor字段。QIM_ACTUAL_ARRIVAL_RATE_FILE改写 committed rate;QIM_LOADGEN_SUMMARY_FILE写入键值摘要。集成脚本用--minimum-ratio 0.99解释该文件。QIM_ARTIFACT_DIR是显式工件根目录;未设置时隔离 wrapper 创建路径、打印并保留它。工件记录 git 状态与统计而非完整 diff,且不含 token 或消息正文。QIM_OUTBOX_RETENTION_MS/QIM_OUTBOX_RECOVERY_WINDOW_MS由 integration wrapper 统一校验和导出;不能仅设置 fanout 环境变量而没有同值的 broker topic config。
5. 边界与禁止项¶
- 不修改 gateway/session 的分页实现、服务端指标定义、混沌注入、Scylla/Redpanda 拓扑或容量目标。
- 不把 raw socket write、首页大小、日志 grep 或空样本当作提交/投递/指标通过。
- 不把短诊断、单机 Docker、未实现的 mix/backlog/cold 场景标成发布证据。
- 不删除失败工件,不输出认证 token、消息正文或其他敏感环境变量。
6. 验证计划¶
| 层级 | 必须验证 |
|---|---|
| 单元 | 0/non-finite rate 与 0 clients 被拒;99% 覆盖率边界;分页唯一性/重复 cursor 判定;summary 口径。 |
| 脚本 | assert-arrival-rate 在 99% 边界、低于边界、非法 ratio 下行为正确;bash -n 通过。 |
| 集成(可选,主线程执行) | integration/run.sh smoke 走 smoke 而不创建/断言性能速率;短隔离诊断产生服务/依赖日志、环境、五服务 metrics 和 loadgen summary。 |
| 不执行 | 不运行 180 秒、目标速率或容量压测;服务端未实现分页时不把 T-HEAVY 失败归因于 loadgen。 |
7. 风险¶
- 严格分页核验会暴露当前 gateway/session 未透传 page cursor 的缺口,使现有 5000 会话 T-HEAVY 从假通过变为失败;这是预期的真实性修复,服务端修复不在本 Delta 范围。
- 99% committed/coverage 门槛可能暴露过去被 socket write 或少量样本掩盖的吞吐/时延问题;这同样是预期结果。
- 增加指标抓取要求运行环境有
curl且五个指标端口可达;缺失应阻断发布,而不能降级为日志 grep。
8. 复杂度¶
M:修改仅限一个负载工具和其脚本编排,接口局限在现有内部模块;不需要服务端架构变更。