fix: preserve cross-pod message order
This commit is contained in:
@@ -694,3 +694,52 @@ ACK 从 WS 队列入队到 socket write 完成只增加约 0.3至0.6ms,而客
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r4-1001/metrics.jsonl`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r4-1001/server-metrics/`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r4-1001/im-server-{0,1,2}.log`
|
||||
|
||||
## 24. 900 人混合 R5 顺序复测
|
||||
|
||||
Run ID:`s900m-mixed-r5-1001`。本轮在 R4 相同的 900 条 WebSocket、135 对单聊用户和 224 个群发送者负载下,验证长延迟直方图、Cluster gob 类型修复及消息顺序。
|
||||
|
||||
| 指标 | 结果 |
|
||||
|---|---:|
|
||||
| 就绪连接 | 900 / 900 |
|
||||
| 发送尝试 / 90 秒命令窗口内 ACK | 1798 / 1797 |
|
||||
| 晚到 2xx / 最终接受 | 1 / 1798 |
|
||||
| 明确拒绝 / 最终未知 | 0 / 0 |
|
||||
| 超过 20 秒的 ACK | 375 |
|
||||
| ctrl ACK P95 桶 / 精确 ACK P95 | 45s / 41746.854ms |
|
||||
| 单聊对端实时投递 | 1350 / 1350 |
|
||||
| 群聊实时投递 | 403200 / 403200 |
|
||||
| 实时总投递 / 丢失 | 404550 / 404550,0 丢失 |
|
||||
| 重复 / 乱序 / 断连 | 0 / 1 / 0 |
|
||||
| 历史回查 | 1798 / 1798 |
|
||||
| 无及时 ACK 消息历史命中 | 1 / 1 |
|
||||
| MySQL 精确命中 | 1798 / 1798 |
|
||||
| MySQL 缺失 / 错配 / 重复 / 额外 | 0 / 0 / 0 / 0 |
|
||||
| Pod Ready / 重启 | 3 / 3,0 重启 |
|
||||
|
||||
唯一超时消息 `s900m-mixed-r5-1001-g-a-0136-02` 在 95.028 秒收到 202,因此属于晚到成功,不是拒绝或丢失。压测报告已区分 `publish_accepted`(命令等待窗口内)与 `publish_final_accepted`(包含晚到 2xx);用新口径重算后发送成功率为 100%,报告只因真实乱序而失败。长延迟直方图的 P95 正确落在 45 秒桶,不再退化为最大值。
|
||||
|
||||
本轮唯一乱序发生在 A 机 97 号连接的同一单聊 Topic:客户端先收到 seq=322,后收到 seq=321。两条消息由会话两端在几乎同一时刻发送,服务端均实时投递并精确落库,所以问题不在 MySQL、Kafka 或历史回查,而在 Topic master 到 proxy Pod 的实时转发顺序。
|
||||
|
||||
代码检查确认,同一个 multiplex session 每次入队都会调度 `clusterWriteLoop`;此前没有排他状态,多个 worker 可以同时消费同一个 `send` channel。随后使用 fire-and-forget RPC 时,先取出的 seq=321 与后取出的 seq=322 会在远端并发执行,导致 seq=322 先进入 proxy Topic。该竞态与本轮现象完全一致。
|
||||
|
||||
修复内容:
|
||||
|
||||
1. multiplex session 增加原子调度所有权,同一 session 同时只允许一个 Cluster 写任务排空;释放所有权时再次检查队列,覆盖入队与退出之间的竞态。
|
||||
2. Master 到 Proxy 的同一 Topic 响应改为逐条等待 RPC 完成,保证远端处理完 seq=N 后才发送 seq=N+1;不同 Topic 仍由 worker pool 并行处理。
|
||||
3. 新增本地 RPC 回归测试,故意延迟 seq=1 的处理并重复调度同一 session,验证接收顺序始终为 1、2;该测试在 `go test -race` 下通过。
|
||||
4. 压测工具新增晚到 2xx 最终接受计数,已解决“最终已 202 但报告仍算发送失败”的重复判错。
|
||||
|
||||
服务端三个 Pod 共记录 1798 条 ctrl ACK,分布为 574/611/613;enqueue/write 平均约 60至66ms,P95 均不超过 250ms。未出现 Topic、Cluster proxy、WS send queue full、Kafka 错误、WS text write 错误或 Pod 重启。A/B 回调队列峰值为 253/290,最大等待 10.703/5.929ms,结算时均已排空。完整 Pod 日志中未再出现 `types.KVMap` 或其他 gob 注册错误,证明 R4 后的 Cluster gob 修复已生效。
|
||||
|
||||
本轮 MySQL 校验覆盖 `im_008_group_messages_202610` 与 `im_008_messages`,1798 条业务消息全部精确命中。结论是持久化、实时到达、长 ACK 统计和 gob 修复均通过,当前唯一阻断项为已完成代码修复但尚待发版复验的跨 Pod 顺序竞态。
|
||||
|
||||
下一步发版后执行完全相同的 900 人混合 R6。R6 通过条件为:最终接受 1798/1798、实时投递 404550/404550、重复/乱序/断连均为 0、历史和 MySQL 均为 1798/1798;ACK 延迟继续观测但不作为阻断门禁。
|
||||
|
||||
新增产物:
|
||||
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r5-1001/report.json`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r5-1001/db-verification.json`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r5-1001/metrics.jsonl`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r5-1001/server-metrics/`
|
||||
- `loadtest/im-pressure/results/s900m-mixed-r5-1001/im-server-{0,1,2}.log`
|
||||
|
||||
Reference in New Issue
Block a user