Files
SerpMax/stress/REPORT.md
T

5.6 KiB

ProfileMax(CloakB + ipmart.io-US)并发常驻浏览器压测报告

  • 日期:2026-10-09
  • 服务器:OVH-FR 37.187.92.169(8 核 / 31GB 内存 / /dev/shm 16G / 同机还跑 mysql、clickhouse、plausible 等其它服务)
  • 链路:ProfileMax admin(127.0.0.1:5310)→ 节点 OVH-FR(node :3106,systemd 直跑,无 Docker)
  • 测试身份:MCP 用户 phptits(id=2);Profile 全部归属该用户
  • 方式:节点 API POST /profiles/:id/lease(ttlMs=2h) → POST /profiles/:id/browser/start → CDP /json/new + WS Page.navigate 开真实页面;每 20s 扫 /proc 按 --user-data-dir 聚合每 Profile 进程树
  • 内存口径:PSS(smaps_rollup,去共享重复);RSS 会把共享页重复计数(报告注明)

配置

项 值
浏览器内核 CloakB(cloak,146.0.7680.177.5)
代理 ipmart.io-US(socks5 gateway.ipmart.io:9999,用户名含 {sid} → 每指纹独立 US 住宅 sticky 出口)
标签 SERP
模式 无头(用户中途指示全部改无头)
保活 BROWSER_IDLE_TIMEOUT=0(禁用 10 分钟空闲自动关闭)+ 每 Profile 2 小时 lease
Profile 池 10,002 个(sz-serp-*,CloakB + ipmart.io-US + SERP)

结果总览

指标 测试1:3 标签(google/yahoo/x) 测试2:1 标签(google)
同时常驻浏览器上限 82 个 189 个
常驻时长 ≥40 分钟(最老的) ≥40 分钟(最老的)
系统峰值 PSS 25.0GB 25.5GB
内存最低可用(avail) 542MB(耗尽) 2793MB
swap 峰值 9.2GB 全满(耗尽) 7.6GB(触发停止线)
load 峰值(8 核) 118(kswapd 抢转,CPU 也耗尽) 46
总进程/线程数峰值 1280 进程 1702 进程
每浏览器进程数(均值) 15.1(重载页到 50+) 9.0
每 Profile 内存(稳定期) p50=125 / p90=906 / max=1560 MB;总量均值 ≈305MB p50=152 / p90=158 / max=179 MB;总量均值 ≈129MB
每 Profile swap p50=20MB p50=2MB
每 Profile CPU(约 40 分钟常驻) 均值 ≈164s 均值 ≈46s
每 Profile 磁盘(user-data) p50=25MB / max=115MB p50=10MB / max=115MB

结论:当前服务器(31GB 内存,其余 3.7GB 被 mysql/clickhouse/系统占用)

  • 3 标签(轻量页)可常驻 约 80 个 Profile;3 标签里出现 yahoo/x 重页时重载 Profile 会拖到 1.5GB/个,是方差的主因。
  • 1 标签(google)可常驻 约 190 个 Profile(停止在 swap 7.2GB 保守线,真实极限约 200±10)。
  • 内存是第一瓶颈,PSS 是衡量口径;3 标签场景 CPU(kswapd + 软渲染)会成为第二瓶颈。

每轮细节

测试1(3 标签)

  • 发射阶段:并发 4,fd 修复后从 58 → 82 一路推进;MemAvailable<1.5GB + swap 满后页面加载/启动开始超时与抖动(load 118),停止发射。
  • 残留 82 个全部驻留至数据采集完成(带 OOM 保护策略:浏览器主进程 oom_score_adj=200,其它服务进程=-600,整个压测期间 mysqld/clickhouse/PG 等零损伤)。
  • 重载 Profile(x.com/yahoo 富页)实测会把进程树拉到 50+ 进程 / 1.5GB PSS。

测试2(1 标签)

  • 清场回收后重跑同一 10002 池;发射 25 分钟到 189 个,唯一失败 1 次;swap 7458MB ≥ 7200MB 触发保守停止(avail 仍有 3.3GB,真实极限略高)。
  • 单标签 google 的内存分布极稳(129MB 均值,极差 179)——google 轻页没有长尾。

过程中修复的 Docker/系统/产品问题

  1. fs.file-max=65535 系统级文件句柄上限——58 个浏览器即吃满(65216/65535),新 chrome 启动静默失败 → 启动超时。已放宽:fs.file-max=2097152(已写入 /etc/sysctl.conf)。
  2. inotify 额度:max_user_instances 128→1024、max_user_watches 261756→524288(chrome 每 Profile 多个 watcher,128 实例上限也会卡死启动)。
  3. swap 仅 1GB:追加 8G swapfile /testswap(priority 10),现共 9GB,保留作为长期优化(防 OOM 误伤同机其它服务)。
  4. 10 分钟空闲自动关闭(节点 BROWSER_IDLE_TIMEOUT 默认 600s):测试期间置 0 禁用,已恢复默认。
  5. 有头模式(浏览器经 VNC/WebDesk 跑在每 Profile Xvfb 上,llvmpipe 软渲染)在批量场景会瞬间把 8 核打满(load 96),批量常驻必须用无头;webdesk 二进制与 x11vnc 测试期间暂移、已恢复。
  6. 产品坑(记录进记忆):节点有「UI 误关自动复活」(SIGKILL 杀浏览器会被复活,重启风暴);停浏览器必须走 API 显式 stop(closing 路径)。browser/start 返回的 processId 是包装进程(拉起 chrome 后退出),不能当存活判据;存活判据应按 --user-data-dir 进程树聚合。响应体统一 {success,data} 包装。
  7. admin DELETE /api/profiles/:id 只删库行、不清理节点侧 Profile 数据(节点清理只在转移链路触发)——压测清理需要另对节点调 DELETE /profiles/:id?force=true(本次已处理)。

清理与恢复

  • 测试 Profile:admin 侧 10,002 个全部删除;节点侧已启动过的 190 个数据目录全部强删(force=true);节点现存 139 个目录均为合法 Profile(未动)。
  • 配置:webdesk 二进制、x11vnc、BROWSER_IDLE_TIMEOUT、全部恢复;fs.file-max/inotify/8G swapfile 保留(系统优化项)。
  • 终态:节点在线(0 running)、admin 正常、内存回收(avail 29GB)、swap 余量 6.2GB。

复现物

  • 服务器 /root/serpmax-stress/:create-profiles.ts / run-stress.ts / sampler.ts / stop-browsers.ts / report.ts / cleanup-profiles.ts / node-wipe-stress.ts
  • 数据:data/test{1,2}-summary.json|md、data/test1-stats-final.jsonl(154 轮)、data/test2-stats.jsonl(117 轮)、各轮 run 日志
  • 本地:/home/bigcode/data/dev/bun/SerpMax/stress/REPORT.md(本文件)+ 同套脚本与 summary JSON