---
type: arch
status: active
created: 2026-09-01
step: S5 / plan-20260901-01 / run-20260901-browser-arch
---
# onesvm-browser-server 最终方案 v1(用户 review 版)
> 时间口径 Asia/Shanghai。本文整合:S1 调研(`research/01–05`)、S2 筛选(`select.md`)、
> S3a 代理探活(`proxy-probe.md`)、S3b/S3c 本机 Docker 实测(`bench/S3b-summary.md` / `S3c-summary.md`,原始数据 `bench/*/results.json`)、
> S4 架构设计全文(`docs/design-arch-20260901.md`,机制细节权威;冲突处以本文为准)。
> 本文所有性能数字均为 **2026-09-01 本机实测**(darwin arm64 / Docker Desktop 29.4.0),非纸面推算;外推处显式标注。
> **权威关系**:本文为决策与结论权威;机制细节权威为 design-arch(冲突处以本文为准)。
```mermaid
flowchart LR
C[智能体消费者
Vlepontas / EAI / 注册主体] --> G[统一出口网关 ×N 无状态
MCP 主 + HTTP 兜底 · X-Service-Token]
G -->|overlay enqueue| S[scheduler 单副本
SQLite WAL 队列 · ADMIT_MAX=60]
S --> D{Dock 适配器}
D --> A[A 无浏览器
SearXNG-CN/Global · Trafilatura]
D --> B[B 轻渲染
Lightpanda]
D --> H[C 保真按需槽
chrome-headless-shell]
D -.插拔预留.-> HD[(有头档·默认不部署)]
B & H --> P[ProxyManager 单副本
mihomo · vless 热池 · 合规路由]
A -->|国内域| DI[国内直连]
A -->|境外搜索| P
G --> POL[合规拦截·策略包单源
请求侧@网关 / 响应侧@worker模版层]
```
---
## 0. TL;DR
1. **1GB 够开机、也够维持 Vlepontas 60 会话级 + EAI 日常使用**——前提是三条纪律:60 = 队列深度而非浏览器并发;渲染槽 ≤5 且重页互斥;保真 Chrome 槽按需启动。详见 §2 与 §7-D1。
2. **实测最痛的不是内存,是上游反爬**:60 并发裸打 SearXNG,百度/搜狗全灭(CAPTCHA)、必应中国 60/60 扛住;国外方向数据中心 vless IP 下 Google/DDG/Brave 全灭、只有 Bing 出结果。两者都由「网关排队 + 每 host 限速 + 缓存」消化,不由加内存解决。
3. **入选 5 套**:国内 `SearXNG-CN` + `Trafilatura-HTTP`;国外 `SearXNG-Global`(带质量警示)+ `Lightpanda` + `chrome-headless-shell`。预留 `Camoufox`(强对抗,需住宅代理)。
4. **架构零 Redis**:SQLite WAL 队列 + 进程内快通道;网关无状态 ×N,scheduler/ProxyManager 单副本。
5. 需你拍板 6 个决策点(§7),最关键的是 **D1 内存档位** 与 **D2 国外搜索质量路线**。
---
## 1. 任务 1:统一消费出口
设计全文:`docs/design-arch-20260901.md` §2。要点:
- **注册/凭证**:`Consumer`(注册主体:vlepontas、eai…)+ `ApiKey`(可吊销、带 scopes/rpm/日配额/月配额/并发会话数)+ `QuotaLedger`(预扣防超卖)。明文 key 只回传一次,库存 hash,`hmac.compare_digest` 比对。
- **双形态同一内核**:MCP Server 为主(`POST /mcp`,Streamable HTTP,无协议会话态)+ HTTP API 兜底(`/v1/search` `/v1/read`,`/v1/extract` 特权);同一 Auth → Policy → Queue → Engine 流水线,错误码两面对齐。
- **认证头遵循组织 service-secret-protocol**:静态 key 走 `X-Service-Token: bs_`,🔴 禁 `Authorization: Bearer` 塞静态 secret;密钥 `${VAR:?required}` fail-closed。
- **urlapi**:HTTP 监听独立端口(**提议 `:8640`**,见 §7-D3;S4 原设计值 `:8300` 与 dev-swarm `voc-analysis-dev` 冲突,已改),反代前缀 `/bs-api`(对齐组织 `/search-api` 先例),strip 后转发。
- 管理面(签发/吊销 key)仅 overlay 内网 + 独立 admin token,CLI + SQL 先行。
## 2. 任务 2:集群规格与无 Redis 排队(bench 校准后)
### 2.1 排队机制(零 Redis)
**入队路径**(跨文档统一定义):消费者 → gateway(无状态:认证/配额预扣/合规预检)→ **overlay 内网 `POST /enqueue`** → scheduler(**SQLite 唯一写者**)进程内 bounded queue 快通道 + 立即落 SQLite WAL → 落盘成功才经 gateway 向消费者 ACK 排队位。scheduler 不可达时 gateway 返回 503 + `Retry-After`(fail-closed,gateway 本地不落盘)。执行侧:scheduler 用 `UPDATE…RETURNING` 原子抢单派发 worker;租约 + reaper 收割 + 指数退避(`attempts≤2`,仅瞬时错误重试)+ 死信表。背压三层:`ADMIT_MAX=60`(running+queued 合计)→ 超限 503/429 + `Retry-After` 只拒新不杀旧。理由与机制细节:design-arch §4。
### 2.2 实测内存底账(2026-09-01 cgroup 口径)
| 组件 | idle | 单会话峰值 | 60 burst 峰值 | 建议 cgroup |
|---|---:|---:|---:|---:|
| searxng-cn | 99 MB | 122 MB | 170 MB | 192m |
| trafilatura-http | 33 MB | 35 MB | 41 MB | 64m |
| searxng-global | 122 MB | 150 MB | 181 MB | 192m |
| lightpanda | **3.6 MB** | **251 MB**(重 Shopify 页) | 143 MB | 320m |
| chrome-headless-shell | 37 MB | **394 MB**(同页) | 179 MB | 400m |
| mihomo(代理数据面) | 小(探活期运行平稳;RSS 未单独采样,**估算·待部署后校准**) | — | — | 64m |
| gateway + scheduler(Go/Rust 单二进制+SQLite,估算·待首轮实现校准) | — | — | — | 96m 合计(64m+32m) |
### 2.3 渐进档位表(实测校准版)
**记账口径**(P1-1 修订):「档标」= **常驻业务峰预算**(实测 idle + burst 峰值推算 + 余量);各组件 cgroup limit 是**防暴走天花板,允许超配**(上限合计可超档标)——重页峰值由渲染互斥调度保证不同时发生,超限杀 worker 不杀网关。实测依据:§2.2 底账。
| 档 | 档标(常驻业务峰) | 实测 idle / 业务峰推算 | cgroup 天花板合计 | 组成 | 能力(实测/换算) |
|---|---|---|---|---|---|
| **L0 起步 ~350MB** | ~350MB | idle ≈178MB / 峰 ≈257MB | 352m | gateway×1(64m) + scheduler(32m) + searxng-cn(192m) + trafilatura(64m) | 国内搜索+正文精读全开;搜索单发 p50 0.63s;读取 p50 0.06s |
| **L1 标准 ~700MB** | ~700MB | idle ≈350MB / 峰 ≈627MB | 960m | L0 + ProxyManager(32m) + mihomo(64m) + searxng-global(192m) + lightpanda(320m) | 国外搜索(仅 Bing 可用,见 D2)+ 轻渲染 4 槽(实测 2.13 jobs/s) |
| **L2 满配 1GB** | ≤1GB | idle ≈380MB / 峰 ≈660MB | 1024m 常驻;shell 按需 400m **非常驻**,与 lightpanda 重页互斥 | L1 + gateway×2(+64m) + shell 按需槽 | +保真渲染 1 槽(实测 FIFO 60/60、74s 零拒绝) |
| **L3 舒适 1.5GB(扩容提议,见 D1/§2.5)** | ~1.5GB | —(推算) | ~1536m | L2 且 shell 常驻 400m + searxng-cn/global 各 ×2 + 余量 | 渲染槽 4+1 免互斥;搜索双副本冗余;见 §2.5 换算 |
| **L4 强对抗档(另议)** | 3–4GB + 住宅代理 | — | — | + Camoufox ×2(150–300MB/实例) | Amazon/Medium 级 WAF 目标(实测确认数据中心 IP 打不过) |
**节点布局**:【2026-09-01 用户更正】目标环境为 **primary 生产 Swarm(mgr1 .51 / mgr2 .52 / mgr3 .53)**,非 dev-swarm。**测试期全部署于 mgr1 单节点**;扩展期:mgr1 控制面(scheduler + ProxyManager + 本地卷 SQLite + gateway×1)、mgr2 国内组+轻渲染(searxng-cn + trafilatura + lightpanda)、mgr3 国外组+保真(searxng-global + shell 按需槽 + gateway×1)。有状态钉节点,网关可漂移。部署细节权威为 `deploy-prod-preset-20260901.md`。(原 dev-swarm .61/.62/.63 布局作废——1GB 内存约束与档位表不变。)
> 注(P6 F1):若适配器采用 scheduler 进程内形态(deploy 预设 D8),scheduler 由 32m 提额至 64m,L2 常驻天花板 1024m → 1056m(超配口径,档标不变)。
### 2.4 为什么 60 不是 60 个浏览器(实测证据)
- chrome-headless-shell `CONCURRENT=1`:60 任务全部 FIFO 入队、顺序执行、**0 拒绝、0 OOM**,墙钟 74s。
- lightpanda 4 槽:60/60 全过,28s。
- searxng-cn 裸 60 并发:HTTP 全 200 但断言仅 4/60——**瓶颈是百度/搜狗 CAPTCHA**;必应中国 60/60、360 53/60。结论:网关把对上游并发钳在 4–8 + 每 host 最小间隔 + 短缓存,队列深度照常 60。
- 注意:国内反爬按**出口 IP**计,dev-swarm 出口 IP 单一,**多副本不能分散 CAPTCHA**,只能靠限速与缓存(这是设计结论,不是缺陷)。
### 2.5 负载模型与扩容换算(D1 的决策依据)
**实测吞吐锚点**(bench 原始数据换算):
| 通道 | 实测 | 持续吞吐换算 |
|---|---|---|
| 国内搜索(searxng-cn) | 单发 p50 0.63s | 上游钳 6 并发 → ≈9.5 qps |
| 国外搜索(searxng-global,仅 Bing) | T3 p50 4.68s | 钳 4 并发 → ≈0.85 qps(质量受限见 D2,非容量受限) |
| 正文读取(trafilatura) | p50 0.058s @8 并发 | 服务侧潜力 ≫100/s,瓶颈在上游站点限速 |
| 轻渲染(lightpanda 4 槽) | 60 任务/28.2s | **2.13 jobs/s** |
| 保真渲染(shell 1 槽) | 60 任务/74.0s | **0.81 jobs/s** |
**负载模型**(假设·比例待你校准):60 会话活跃,每会话每分钟 2 次搜索 + 3 次读取 + 0.1 次渲染 → 搜索 2 qps、读取 3 qps、渲染 0.1 jobs/s。
**结论**:L2(1GB)稳态占用率——国内搜索 ~21%、读取 ~3%、渲染 ~5%,**可维持 Vlepontas 60 会话级 + EAI 日常负载**;压力只在「60 同发突发」与「重页叠加」两个瞬间,由队列(ADMIT_MAX=60)与渲染互斥消化。
**L3 1.5GB 的增量价值**:① shell 常驻,省每次冷启动(估算 5–10s/次·未单独测);② 重页免互斥,消除渲染互斥排队等待;③ searxng 双副本,滚动重启不断流;④ gateway×2 滚动发布不断线。**提议:1GB 承诺不变先上线 L0→L2;若渲染等待或重页互斥成为日常痛点,再申请升至 L3(dev-swarm 节点各 6.5GB,1.5GB 总预算宽裕)。**
## 3. 任务 3:Dock 协议 + 整合器 + 统一输出
设计全文:design-arch §3。要点:
- **DockAdapter 五方法**:`init / health / execute / teardown / capabilities`;`health()` 强制上报 `rss_bytes / startup_ms / slots_free`;适配器负责「统一意图 → 引擎原生调用」的输入转换,**只产出 RawResult**;「RawResult → 统一信封」的输出整合(Size guard → fit markdown → 安全扫描 → Schema 封装)收敛在 **Dock worker 共享模版层(整合器)**,词表/规则单源版本化,N 个适配器零合规代码(S7 架构审查锁定);回收按 N 页/T 分钟硬重启。
- **统一输入两类意图**:`Search{query, max_results≤20, time_range?, lang?}` 与 `Read{url, formats=[markdown], max_chars, extract?}`;第三类 `browse` 协议预留默认关闭。
- **消费者自选国内/国外**:MCP 工具暴露 `region: domestic|overseas` 参数(对应任务 3 的「两种接口类型」),消费者按 MCP 文档自行选择;网关仍按域名路由表强制合规(选了 overseas 也不会把国内域送代理)。
- **统一 AI 原生信封**:`{ok, kind, request_id, took_ms, usage{credits,engine,tokens_estimate}, provenance{url,retrieved_at+08:00,adapter,proxy_exit,cached}, error{code,message,retry_after_s?}}`;search 给 `results[{title,url,content≤800字,score 0–1,engine}]`;read 给 fit markdown(实测提纯:Shopify 壳页 1.44MB HTML → 2.9–3.4KB 正文,约 **420–500 倍**,lightpanda/chrome 两内核样本)+ 可选 extract 旁路(默认零 LLM 路径:JSON-LD/OG/CSS);错误码 `blocked|denied|timeout|quota|rate_limited|extract_failed|upstream` 与 HTTP 对齐。
- **降级链**:C(保真)槽满 → B(轻渲染)→ A(HTTP+fit)→ `blocked/upstream`,不静默降数据质量。
- **有头浏览器仅抽象插拔预留**:Dock Protocol 预留 `render=full+headful` 能力位(有头/Camoufox 档),默认不装镜像、不占内存预算。
## 4. 任务 4:ProxyManager + 合规双向保险
设计全文:design-arch §5。要点:
- **数据面 mihomo + 控制面自研**(单副本):订阅解析(实测 SUB-1 为 Clash YAML,69 节点:vless 52 全活、hy2 17 容器 UDP 全灭弃用);多订阅容灾位已留(SUB-2 待你提供);探针 `google generate_204`,活跃出口 30s、全池 5min/轮;P2C 轮换 + 同域名 sticky;主圣何塞(167ms 实测)备东京。
- **域名路由表**:国内域/`*.onesvm.com` → DIRECT;黑名单 → deny;高对抗域 → 标记 render=full;默认境外 → vless 池。
- **生产侧出口拦截**(统一策略包单源 + 两个执行点,Schema 之前,MCP/HTTP 共用):**请求侧在 gateway**(入队前:SSRF fail-closed 每次重定向重验、仅 80/443 → 域名 blocklist + robots 普通 key 遵守);**响应侧在 Dock worker 共享模版层**(fetch 后、封装前:体积/Content-Type 白名单 → 关键词分类词表对齐《生成式 AI 办法》第 4 条(NFKC 归一,高危 block,PII 默认 redact)→ 注入防护包裹)。词表版本化(`wordlist_version` 入审计)。命中合规即 `error.code=denied` 并写审计(`consumer_id,url,rule_id,ts+08:00`),不假装成功。
- **消费侧 MCP 文档规则**(server instructions 固化):不得用于非法采集、破登录/支付墙/验证码(默认无此能力)、整站搬迁式 crawl、汇总公开个人信息成档案、把含境内个人信息的 query 发往境外引擎。
- **法律主路径结论**(research/05,非法律意见,上线前法务复核):境内集群拉境外公开网页回境内 ≠ 数据出境;但一旦走境外托管 SaaS(Tavily/Jina 云)query 即出境 → 默认境内闭环。
- 订阅 URL 只进环境变量;节点凭据脱敏;日志禁记 key 明文/query 原文(记 hash+长度)。
## 5. 任务 5:实测评定结论
评分卡(权重:内存三档 30% / 质量 25% / 成功率 20% / 延迟 15% / 运维 10%;门槛 综合≥60):
| 方案 | 组 | 综合分 | 实测亮点 | 实测短板 | 结论 |
|---|---|---:|---|---|---|
| trafilatura-http | 国内 | **96.8** | 60/60、p50 0.06s、41MB burst | gov.cn 联播壳页 favor_precision 弃取(能力边界) | **P0 默认开机** |
| searxng-cn | 国内 | **71.5** | 单发 5/5、p50 0.63s、政策域命中准 | 60 burst 断言 4/60(百度/搜狗 CAPTCHA;bing-cn 60/60) | **P0**(须网关排队钳 4–8 + 短缓存) |
| lightpanda | 国外 | **91.0** | idle 3.6MB、JS 对照 3/3、T5 60/60 | 重 Shopify 页 251/320m;CF/Amazon 过不去 | **P2 默认 JS 核** |
| chrome-headless-shell | 国外 | **85.5** | JS 对照 3/3、Shopify 列表价更完整、单槽 FIFO 零拒绝 | 重页 394/400m;Medium/Amazon 仍拦 | **P3 保真槽(L2 按需 / L3 常驻)** |
| searxng-global | 国外 | **62.0** | 实例稳、181MB burst 安全 | T3 断言 0/5:vless 数据中心 IP 下 Google/DDG/Brave 全 CAPTCHA/429,仅 Bing 且偏题 | **擦线入选**,部署但产品层不承诺多源(见 D2) |
**排除**:playwright-distributed(Redis 硬依赖)、browser-swarm(仅 macOS,不适配 Swarm)、Browserless(官方建议 4GB 档,重)、Jina reader:oss(捆绑 Chrome+LibreOffice;云端出境)、FerrumMCP/firefox-docker-mcp(生态弱)、Bouncy(无官方镜像、维护风险,列备选)。
**预留**:Camoufox(强对抗,须住宅代理,150–300MB/实例)→ L4 档。
**强对抗事实**:Amazon WAF 验证页 / Medium Cloudflare / Reddit 匿名 403——本代理池打不过,设计记 `blocked` 交预留档,不加并发硬刚。
复跑入口:`bench/<方案>/run.sh`(无密钥);代理 `bench/proxy/up.sh`(读 `PROXY_SUB_URL`)。
## 6. 任务 6:交付 review
即本文。请你重点过:§2.3 档位表、§5 评分与结论、§7 决策点。
## 7. 决策点(请你拍板)
| # | 决策 | 我的提议 | 依据 |
|---|---|---|---|
| **D1** | 内存档位 | **先按 L0→L2 渐进上线(≤1GB 承诺不变);若渲染互斥/冷启动成为日常痛点,再申请升 L3 1.5GB**。1GB 稳态可维持(占用率见 §2.5),L3 增量是体验与冗余 | §2.2/2.3 实测底账 + §2.5 换算 |
| **D2** | 国外搜索质量路线 | 三选一:**a)** 接受「仅 Bing + 可能偏题」零成本先用;**b)** 补充更优质代理套餐/住宅出口(成本项,质量恢复多源);**c)** 接 Brave Search API 等官方 key(质量好,但 query 出境,须法务确认 + 特权 scope)。提议 a 起步、b 列入采购、c 仅特权 | S3c §2 引擎矩阵 |
| **D3** | 端口与前缀 | **`:8640` + `/bs-api`**(`:8300` 已被 voc-analysis-dev 占用;8640 邻近 WSG 8620 段,无冲突;确认后同步 inventory) | inventory §3.2/§5 |
| **D4** | 域名策略默认姿态 | blocklist + 高危类 deny(白名单档做成可选配置,政企交付再开) | design-arch §5.4 |
| **D5** | Camoufox 强对抗档 | 暂不建;等你确认有 Amazon/Medium 类刚需 + 住宅代理预算再启 L4 | S3c §7 |
| **D6** | MCP 兼容 | 首版仅 2026 Streamable HTTP 无状态;出现旧客户端再加 2025 腿 | research/01 §4.1 |
其余开放问题(SUB-2 容灾订阅、审计留存期、境外 SaaS 特权通道、办法适用性法务判定、scheduler 卷备份演练、amd64 复测、镜像 tag 约定等)见 design-arch §8 O1–O13。
## 8. 产物索引与验收状态
| 产物 | 路径 |
|---|---|
| 架构设计全文(任务1–4) | `docs/design-arch-20260901.md` |
| 调研 5 份 | `.dsh/artifacts/run-20260901-browser-arch/research/` |
| 候选筛选+评分卡 | `.dsh/artifacts/run-20260901-browser-arch/select.md` |
| 代理探活 | `.dsh/artifacts/run-20260901-browser-arch/proxy-probe.md` |
| 实测汇总+原始数据 | `.dsh/artifacts/run-20260901-browser-arch/bench/` + `bench/` |
| 实测计划/模板 | `bench/plan.md` |
| Verify / Reverify / Arch-Review | `.dsh/artifacts/run-20260901-browser-arch/{review,reverify,arch-review}.md` |
验收链(已闭环,各经一轮 ITERATE 修订后复审通过):**S6 Verify PASS → S6 Reverify PASS → S7 Architecture Review PASS**(报告:`.dsh/artifacts/run-20260901-browser-arch/{review,reverify,arch-review}.md`)。