6.3 KiB
IM allrich 双机压测执行记录
日期:2026-09-27
1. 测试环境
| 项目 | 值 |
|---|---|
| 企业码 | allrich |
| 企业名称 | 大家一起发 |
| HTTP API | https://api.118im.com |
| WebSocket | wss://api.118im.com/v0/channels |
| API Key | 通过 IM_API_KEY 注入,不写入 Git |
| 测试验证码 | 123456,仅测试环境使用 |
| 测试密码 | 通过 IM_LOAD_PASSWORD 注入,不写入 Git |
| 机器 A | 当前开发机,192.168.1.135 |
| 机器 B | 另一台压测机,运行 -machine b |
config.json、.env.test、manifest.json 均被 Git 忽略。manifest 含账号 Token,只能通过受控内网传输。
2. 数据准备结果
2026-09-27 首次准备曾按 2000 账号目标执行。当前分阶段压测使用的实际运行文件为:
users_per_machine=500。- 账号:1000,机器 A/B 各 500。
- 好友关系与 P2P Topic:500 对。
- 测试群:1 个,当前 manifest 的
group_topic=grp3Ita5tyBIMs。
正式的 2000 人群测试前,必须将 users_per_machine 恢复为 1000,在机器 A 重新执行 prepare 和 verify,并将新 manifest 同步给机器 B。不能用当前 1000 人清单宣称已完成 2000 人群压测。
准备过程观察到注册和好友同意接口存在少量瞬时 500/404,100 人群邀请批次存在 502、超过 2 分钟及 IDEMPOTENCY_IN_PROGRESS。工具使用相同业务幂等键和退避重试后全部恢复;这些属于准备链路现象,不计入正式消息到达率。
3. 最新有效轮次
| 项目 | 值 |
|---|---|
| Run ID | p2p500-r5-20260927-05 |
| 场景 | p2p |
| Git 提交 | ea8732e |
| 连接 | A/B 各 500,合计 1000/1000 READY |
| 发送 | 10000/10000 获得 ACK |
| 实时到达 | 10000/10000,到达率 100% |
| 历史落库 | 10000/10000,落库率 100% |
| 异常 | 丢失 0、重复 0、乱序 0、断连 0、发送错误 0 |
| ACK 延迟 | P50 约 650ms,P95 1313ms,最大 2075ms |
| 同机 echo 投递 P95 | 2s 直方图桶 |
| 报告门禁 | 正确性通过;延迟门禁未通过 |
本轮中 A/B 时钟未对齐,A 端记录到 4334 个跨机器负延迟样本,因此不使用跨机器单向延迟作为结论;延迟门禁使用发送机本机 ACK 和 echo 口径。
3.1 服务端阶段耗时
| 阶段 | 平均耗时 | P95 所在桶 |
|---|---|---|
relationship_check |
66.9ms | 250ms |
redis_idempotency |
21.1ms | 100ms |
redis_sequence |
62.7ms | 250ms |
kafka_produce |
11.0ms | 25ms |
save |
116.9ms | 500ms |
meeting_im 和 hotgo 连接池在该轮起压窗口的等待次数和等待时间增量均为 0,未出现连接池枯竭。
3.2 Kafka 和落库
im-server.message_persist的 consumer lag 峰值为 4663。- lag 在发压结束后约 2 分钟清零。
- 测试窗口中批量持久化的单批平均耗时约 3.52s,P95 落在 10s 直方图桶。
- agent 在等待 Kafka 追平后回查历史,10000 条 ACK 消息全部找到,没有持久化丢失。
结论是当前系统能在突发后最终消化积压,但前台 ACK 和异步落库延迟仍高,这两项应单独作为后续优化指标。
4. 历史机器 B 运行文件
以下为首轮历史运行包,不能继续用于新轮次:
/tmp/allrich-machine-b-runtime-p2p-20260927-01.zip
SHA-256: 479f119e7d01e1829c7262cace282c72a5f53ad8e7f5128abc2ade75d046db64
机器 B 必须先安全获取该文件,再执行:
git switch dev
git pull --ff-only origin dev
# 运行包不在 Git 中,必须从机器 A 单独复制
scp youshunlai@192.168.1.135:/tmp/allrich-machine-b-runtime-p2p-20260927-01.zip /tmp/
shasum -a 256 /tmp/allrich-machine-b-runtime-p2p-20260927-01.zip
unzip -o /tmp/allrich-machine-b-runtime-p2p-20260927-01.zip \
-d loadtest/im-pressure
chmod 600 loadtest/im-pressure/.env.test \
loadtest/im-pressure/config.json \
loadtest/im-pressure/manifest.json
set -a
source loadtest/im-pressure/.env.test
set +a
cd loadtest/im-pressure
go build -o im-pressure .
./im-pressure agent \
-config config.json \
-manifest manifest.json \
-machine b \
-coordinator http://192.168.1.135:8090 \
-metrics-listen :9105 \
-output results/p2p-20260927-01/agent-b-summary.json
完整 B 机操作和故障处理见 loadtest/im-pressure/MACHINE-B.md。
5. 多 Pod 口径说明
当前 A/B 配置均使用 wss://api.118im.com/v0/channels 公共入口。该配置验证 LB 实际分配下的多 Pod 能力,但不能保证两台压测机固定落到不同 Pod。若验收要求强制指定不同 Pod,需要提供两个独立 WS 定向入口,分别配置到 endpoints.a 和 endpoints.b。
6. 后续测试顺序
6.1 P0:扩容到 2000 个用户
- 将机器 A 的
config.json修改为users_per_machine=1000。 - 机器 A 执行
prepare和verify,确认 2000 账号、1000 对好友、1000 个 P2P Topic 和 2000 人群都就绪。 - 重新生成包含
.env.test、config.json、manifest.json的 B 机运行包,B 机解压后执行verify。 - A/B 都执行 NTP 校时,要求偏差小于 50ms,否则继续忽略跨机器单向延迟。
6.2 P1:2000 人群聊
使用 scenario=group:
- A/B 各建立 1000 个 WS,合计 2000 个在线群成员。
- A/B 各取前 500 个发送者,每人 2 条,合计 2000 条群消息。
- A/B 交错每 100ms 发送 1 条,单轮发送窗口约 100s。
- 期望实时投递为 2000 条消息 x 2000 连接,即 400 万次有效到达。
- 检查群消息 ACK、每个 WS 的到达数、重复、乱序、断连、
im.group.message.persistlag 和群消息月表落库。
群聊是下一个应执行的场景,因为它直接验证本次多 Pod 改造的 Redis fanout 和群消息 Kafka 持久化。
6.3 P2:混合场景
群聊正确性通过后使用 scenario=mixed:
- 300 对私聊用户双向各发 5 条,合计 3000 条私聊消息。
- A/B 各 250 个群发送者,每人 2 条,合计 1000 条群消息。
- 同时观察私聊与群聊的到达率、两个 Kafka 持久化 Topic 的 lag,以及 Redis、MySQL 和 3 个 Pod 的资源争用。
6.4 P3:单聊完整规模回归
最后在 2000 连接下重跑 p2p,即 1000 对用户双向各发 10 条,共 20000 条。延迟门禁仍为 ACK P95 <= 500ms、同机 echo P95 <= 1000ms;若只有正确性通过而延迟未通过,结论必须标记为“可靠性通过,性能未达标”。