Skip to content

M03 并发阶梯压测与瓶颈分析 · 2026-09-30 ​

拓扑:真双容器(platform-lite + renderer)· 2C/3.8GiB · RENDER_GLOBAL_CONCURRENCY=1 · PAGE_SCREENSHOT_QUEUE_CONCURRENCY=1 · RUNTIME_VITE_TASK_CONCURRENCY=1
混合负载:截图 : 页更 : 构建 ≈ 4:2:1 · 16 个测试用户
证据:stress-report.json 与各档 *-samples.json

1. 阶梯结果 ​

档位工人数时长截图数截图 P50截图 P95吞吐(截图/s)峰值 CPU plat/rend峰值 RSS plat/rend队列峰值写冲突
c4490s1618.6s20.2s0.18174% / 102%1.66 / 0.45 GiB40
c8890s2440.7s43.8s0.27167% / 97%1.82 / 0.46 GiB80
c1212120s3364.0s68.2s0.28109% / 118%0.86 / 0.55 GiB120
c1616120s3587.0s98.1s0.29111% / 113%0.89 / 0.56 GiB160
  • 成功率全程 100%,无 OOM,SQLite write_conflicts=0 / busy_timeouts=0。
  • 页更在 c4 仍 ~0.2s;c12/c16 窗口内几乎被截图占满(0 次完成)——不是页更变慢,是槽位被截图排队占满。
  • 构建 c4:4 次、P50 56s(构建 worker 也是单并发)。

2. 瓶颈判定 ​

text
吞吐天花板 ≈ 0.28 截图/s  →  有效服务时间 ≈ 3.5s/张(单槽)
延迟 ≈ 排队位次 × 3.5s + CPU 争用
c16: 16 × 3.5 ≈ 56s 理论  vs  实测 P50 87s(2C CPU 争用上浮 ~55%)
优先级瓶颈证据说明
P0渲染单槽(RENDER_GLOBAL_CONCURRENCY=1 + 截图队列并发 1)吞吐随并发不涨(0.18→0.29),延迟近似线性;队列深度=工人数加并发只加排队,不加产出
P1构建单 worker(RUNTIME_VITE_TASK_CONCURRENCY=1)c4 构建 P50 56s,且与截图抢 Runtime构建与预览共用 Vite 调度
P22C CPUc4 时 platform 174%(两核打满)单槽下 CPU 已紧;扩槽前需更多核
—内存峰值合计 < 2.4 GiB / 4 GiB不是瓶颈
—SQLite 锁写冲突/busy 均为 0不是瓶颈

3. 结论与建议 ​

  1. 当前 Lite 默认并发 1 是刻意产品约束;在 2C4G 上继续加用户只会拉长 P50/P95,吞吐卡在 ~17 张/分钟(截图)。
  2. 若目标是「5–10 人顺滑」,单槽 + 3.5s 服务时间意味着 P50 排队约 (N-1)×3.5s:5 人约 14s、10 人约 31s——与 c4/c8 实测吻合。
  3. 扩吞吐路径(需改配置/资源,而非调用户数):
    • 提高 RENDER_GLOBAL_CONCURRENCY / PAGE_SCREENSHOT_QUEUE_CONCURRENCY(并配 ≥2 Renderer 或单 Renderer 多槽)
    • 提高 RUNTIME_VITE_TASK_CONCURRENCY 分流构建 vs 预览
    • CPU:≥4C 才有扩槽意义;内存不是约束
  4. 产品文档中的「预览并发约 3」与 RENDER_GLOBAL_CONCURRENCY=1 不一致——名义并发 3 实际被渲染槽压成 1,建议对齐表述或改配置。

4. 未做 ​

  • 提高 RENDER_GLOBAL_CONCURRENCY 后的对照压测(需改 compose 并可能 4C)
  • 构建与截图拆分队列的隔离收益
  • M03-F1(drill 容量拒绝)仍开放