Files
SerpMax/docs/03_XLIGHTPANDA_ROLLOUT.md
T

156 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# xLightpanda 温池切换 + Storage Hook 部署手册(v0.47.0 / xlp 0.10.0)
> 日期:2026-11-03/04。交付:xLightpanda 接管 SERP 浏览器温池 + Storage Hook Phase 1(tmpfs 路由 + 共享 ShaderCache)。
> 代码:SerpMax node v0.47.0(zcode/serpmax-node 已推送);xLightpanda upstream 提交 `4f69ccd2`(0.10.0 显式指纹导入)。
> **部署路径勘误(2026-11-04)**:三节点 systemd 服务 WorkingDirectory=/app,实际运行代码在 `/app/src`(bundle 含 /app/node_modules,勿动);
> `/opt/{serpmax,profilemax}/src` 是滞留副本。部署 = rsync src → 节点 `/app/src` + package.json → `/app` + 更新日期戳 `/app/version` → restart。
## 1. 交付物
| 产物 | 位置 | 说明 |
|---|---|---|
| lightpanda 二进制(ReleaseFast,glibc 2.36 目标) | `/opt/{serpmax,profilemax}/bin/lightpanda` | 222MB;xlp 0.10.0;**必须用 `-Dtarget=x86_64-linux-gnu.2.36` 构建**(节点 Debian 12 glibc 2.36,宿主 2.39 构建会缺 `GLIBC_2.38/__isoc23_strtoull`) |
| SerpMax node 源码 v0.47.0 | `/opt/{serpmax,profilemax}/src` + package.json | xlightpanda kind / SERP_BROWSER_KIND / storage.hook / /storage/hook 端点 |
## 2. 温池引擎切换(每节点)
```bash
# 1) 二进制与代码
rsync -az upstream/zig-out/bin/lightpanda NODE:/opt/serpmax/bin/lightpanda
rsync -az --delete node/src/ NODE:/opt/serpmax/src/ # 源码内含 node_modules 除外
rsync -az node/package.json NODE:/opt/serpmax/
# 2) node.env 追加(二进制路径必配;SERP_BROWSER_KIND 分两步灰度)
grep -q XLIGHTPANDA_BINARY_PATH /opt/serpmax/node.env || \
echo 'XLIGHTPANDA_BINARY_PATH=/opt/serpmax/bin/lightpanda' >> /opt/serpmax/node.env
# 灰度第二阶段才加:
echo 'SERP_BROWSER_KIND=xlightpanda' >> /opt/serpmax/node.env
# 3) 重启并验证
systemctl restart serpmax-node
curl -s localhost:3100/version # 版本号 0.47.0
tail -f /opt/serpmax/data/logs/* # 观察 browser.started_xlightpanda / serp.pool_warm
```
- **回滚**:node.env 删掉 `SERP_BROWSER_KIND`(或置空)→ `systemctl restart serpmax-node`,温池立即回到 Profile kind(veil/cloak)。Profile 元数据不动。
- 温池入池门槛/搜索逻辑(serp-pool.ts)零改动;媒体拦截 `page.route` 与页内 fetch 在 xLightpanda 上已实测(CDP Fetch domain / Runtime.evaluate)。
- xLightpanda 仅无头运行(无渲染引擎);kind=xlightpanda 的 Profile 请求有头(VNC/WebDesk)会显式报错。
## 3. Storage Hook Phase 1(每节点,默认关闭)
配置:`DATA_DIR/node-settings.json` 合并(注意保留既有键;HZ-DE-245 已有 httpCacheDir/profileDir):
```json
{
"httpCacheDir": "…(保留)",
"profileDir": "…(保留)",
"storageHook": {
"enabled": true,
"tmpfsRoot": "/run/serpmax",
"perProfileCacheSizeMb": 256,
"sharedShaderCache": true,
"sharedShaderSizeMb": 256
}
}
```
- 生效后 veil/cloak 浏览器启动前:Cache/Code Cache/GPUCache/Dawn/Media Cache → 每 Profile 独立 tmpfs(256MB 上限);ShaderCache/GrShaderCache → bind 到 `/run/serpmax/shared/shader` 共享 tmpfs。停机/崩溃/hardReset 自动 lazy umount。
- **验证**:`curl -s localhost:3100/storage/hook`(activeProfiles/mounts/recentErrors);浏览器启动后 `mount | grep <profileDir>`;`du` 确认 Cache 目录不再占磁盘;Cookies/IndexedDB 重启保留(路由清单永不含存储类目录)。
- **回滚**:node-settings 置 `"enabled": false` → 重启。挂载失败(无 root/CAP_SYS_ADMIN)自动降级直写磁盘并记 `storage.hook_no_root` 告警,不影响业务。
- xLightpanda 温池实例无此问题(无渲染无 shader cache;HTTP cache 为单 sqlite 文件),storage.hook 只对 veil/cloak 分支挂载。
## 4. 已验证结论(2026-11-03/04,本机)
1. **种子一致性**:6 seed(10000/42/123456/999999/573891/248166)veil-chromium vs xLightpanda 全字段对比,均只剩同 7 处引擎基底差异(canvas/webgl 像素、rects 布局基底、audio DSP),身份字段逐字段一致(xLightpanda docs/SEED_PARITY.md)。
2. **温池可行性**:google 首页入池门槛(搜索框)、登录门槛 evaluate、页内 fetch+DOMParser、route 媒体拦截、导航回退全部通过;fetch 拿到 enablejs 空壳时 results=0 → serp-pool 原有回退逻辑按设计工作。
3. **Cookie 桥**:注入真实形 Google 会话 cookie(SID/HSID/SSID/SAPISID/NID)导航后全部存活。注意:Google 会对请求中出现的**陌生名字** cookie 主动下发删除 Set-Cookie(fake 名必被清,系 Google 侧行为,真实 Chrome 同样)。
4. **Storage Hook**:unshare 用户命名空间实测 18/18 挂载(含带空格目录)、共享 shader 互通、卸载干净、tmpfs 易失语义、disabled 零动作。
5. **导入连贯性守卫**:cloak UA(151)误配 derivation=veil(内核 153)时启动即失败 `InconsistentUserAgentVersion`——node 侧转换器已按 `origin==="veil" && uaMajor===153` 门控。
## 5. 温池灰度现状与遗留问题(2026-11-04)
**当前舰队状态:OVH-ETH-33 已开 xLightpanda 灰度(0.10.5,`SERP_BROWSER_KIND=xlightpanda`);HZ-DE-245 / OVH-DEDI-KS5B 暂保持 veil/cloak 兜底。三节点 lightpanda 0.10.5 二进制已就位;Storage Hook 三节点全启用。**
### 已突破
- 引擎接入全链路可用:克隆启动、impersonate MITM 链、cookie 桥、入池门槛、平均 RSS 75MB(veil 同池 ~450MB)。
- Google 的 **captcha/sorry 硬门已突破**(0.10.2-0.10.4 头集修复:UA-CH 三件套含引号、navigation accept 全段、accept-encoding 值序)。
- **enablejs/critical-ch 软门已突破(0.10.5,2026-11-04)**:给 impersonate-proxy 加了受控转发头 dump(env 门控 `IMPERSONATE_HEADER_DUMP=<目录>`(+可选 `_FILTER=<url子串>),默认零开销;源码在 /home/bigcode/data/dev/impersonate-proxy,该仓库 deployed-but-uncommitted 状态保持),veil vs xlp 同 Profile 同 IP 同 MITM 抓包对比,锁定门因:
- **Accept-CH client hints 全套缺失**。Google 响应声明 accept-ch/critical-ch 后,Chromium 对同源后续请求自动回带全部高熵提示(arch/bitness/full-version(-list)/model/platform-version/wow64/form-factors/prefers-color-scheme/downlink/rtt/ect);xlp 一概不带,Google critical-ch-check 判客户端撒谎 → enablejs 门壳 → hop2 302 /sorry。
- 次要差异:accept-language 多了 `,en;q=0.8` 第三段(veil/Chromium 实测 `de-DE,de;q=0.9` 无英文兜底)。
- 修复:0.10.5 Client.noteAcceptCh/appendClientHints(Accept-CH 持久化+每跳回带,值取自指纹 ctx 高熵集合)+ accept-language 去兜底。
- 验证:ETH-33 xlp 灰度池 pagefetch `ok=true 9 结果 0.9~1.7s`(与 veil 同形);新鲜实例单测通过。
- **已知的非引擎限制**:同一实例被连续高频手打搜索(≥7 次)后会在 navigate 回退跳吃 /sorry——频率疲劳,veil 同样如此,非引擎门;温池轮换天然规避。
### 灰度操作
- 开:`node.env` 加 `SERP_BROWSER_KIND=xlightpanda` → `systemctl restart serpmax-node`。
- 关:删该行 → 重启,立即回 veil/cloak(Profile 元数据不动)。
- 二进制升级:`upstream/zig-out/bin/lightpanda`(ReleaseFast + `-Dtarget=x86_64-linux-gnu.2.36`)→ 节点 `/opt/{serpmax,profilemax}/bin/lightpanda`;先 `sudo pkill -f "lightpanda [s]erve"`(注意 pkill 模式勿自匹配 ssh 命令行,否则 ssh 会话被杀 exit 255)。
## 6. 后续(不在本轮)
- StorageFS FUSE/Rust/Pack(02_STORAGE_HOOK.md Phase 2+),另行立项。
- xLightpanda localStorage/IndexedDB 落盘(SERP 场景 cookie 足够)。
## 6.5 typed 搜索调查(2026-11-04 下午,node 0.49.0/0.49.1)
**用户判断(定稿):go-fetch 打 302/门壳标的 Profile,WebDesk 里 veil 手动输入搜索全畅通 ⇒ 只要 xLightpanda 能像真实浏览器一样打开 google.com 在输入框填词回车,搜索应当没问题;两处部署动作:①`/nodes` 编辑弹窗设置多了加 Tabs 分类;②温池搜索路径保证「粘真实浏览器」。受此推动做的实测链:**
1. **pagefetch 门壳不再直接采信(0.49.0,1475479)**:`~10k Profile 只绑 3 个上游 IP` 的密度下,pagefetch 类 XHR 拿 0 结果/sorry/verify 概率高,而真浏览器路径畅通 ⇒ 改为仅当 `results>0 且 !sorry&&!verify` 采信,其余一律回退 **fill 搜索词 + Enter** 导航路径(真实浏览器行为)。
2. **JS 引导就绪门(0.49.1,55eb63d)**——本地 xLightpanda 复现实锤:
- Google 主包(xjs)未初始化完成时填词提交 → **原生 form GET**(抓到 `biw=&bih=` 空、`ie=GB2312`、无 sxsrf)→ Google 判异常流量 **302 /sorry**(title "302 Moved" 半秒转sorry);
- 等就绪(`readyState=complete` + `gk 命名空间≥30/联想容器 .UUbT9/隐藏域 biw` 有值,约需 10-15s 本地)之后同样操作 → **自然结果**(带 sxsrf/sca_esv 富参数);
- 故 navigate 提交前等待就绪标记(上限 10s,日志 `serp.pool_boot_gate`),温页早已就绪因此实测 `ms≈1-2` 即通过,零延迟副作用。
3. **ETH-33 生产复测:typed 就绪后提交,入参富化正确(sei= 等),但 Google 仍 302→/sorry** —— 剩余根因嫌疑二选一:① 每上游 IP 的 trip 计数(池 64 ≈21/IP, Typed 探针集中于少数 Profile);② impersonate MITM 链对**导航型请求**的头序/TLS 会话特征与真 Chromium 型有残余差异(veilWebDesk 同代理畅通是对照组)。**待 MITM 详查** = `IMPERSONATE_HEADER_DUMP` 开窗抓 xlp 导航 vs 规范浏览器导航头序对比(xlp 0.10.5 已留工具)。
4. 部署注记:node 0.49.1 三节点 `/app/version=20261104.1300`(ETH/HZ/KS5B 全部 xlightpanda 温池态,版本戳一处更新)。
5. admin 1.81.0(144955f):`/nodes` 编辑节点弹窗改 **Tabs 三页(基本信息/存储与缓存/温池与守卫)**;Hook 与守卫面板改为各自「恢复默认」按钮(原「联动恢复默认」取消)。前端已构建,HZ-DE-245 侧 profilemax-admin 已重启生效。
**排查小径(可复用)**:在服务器上 spawn 一只不走 MITM 的 `lightpanda serve` + `/app/node_modules/playwright-core` 装载 typed 探针,可隔离 MITM 因素做二元定位;直连(无 proxy 无 MITM)typed 探针发现 Google 主包就绪但 Enter 提交**不触发导航**,生产池路径(有 MITM)却能正常提交——驱动/键事件传递在直连实例上的差异也收入待修(独立小问题,非 sorry 主因)。
### 6.6 typed 决胜局:生产 dump 对照(2026-11-04 下午二)(0.49.1→0.49.2)
**背景**:用户拿 `24447424 / 2305745 / 65368457` 三只被限 Profile 在 WebDesk(veil)手测**全畅通** ⇒ IP 无恙,差异收敛到 xlp 引擎/MITM 链。用 `impersonate-proxy-dbg`(IMP dump 工具)在生产抓上游可见头,拿到关键证据并各进一环:
1. **生产 dump 三连发(34221790)**:req0 pagefetch XHR(`sec-fetch-mode:cors`/`accept:*/*`,形正常);**req1 typed 导航 = `sec-fetch-site:none` + 无 Referer + 裸 q 提交**(真 Chrome 表单回车应为 `same-origin` + `Referer:https://www.google.com/` + sxsrf 富化);req2(sei= 重定向链,same-origin+referer 正确)。→ 引擎把「激活型提交」送出了地址栏/CDP 型导航特征,Google 判异常。
2. **本地直连 typed 对照(reprobe10/11)**:引导就绪后首轮与结果页二连 typed 均 **organic**(sxsrf/newwindow/sca_esv 富化,10 结果);本地 echo 自建表单提交分类 `same-origin+referer` 正确 ⇒ 引擎直连形态本身良好,问题在生产恢复页态 + MITM 链。
3. **0.49.1 进站门实测有效但不够**:boot 门标志(`readyState+gk/ac/biw`)温页 1-2ms 即过(免延迟),但提交后 Typed 每 0 结果 —— gate 抓的是页内引导而非请求指纹。
4. **0.49.2(55b594c)「typed 回家门」**:pagefetch 门壳回退时若温页是结果/sorry 页,先 `goto google 首页` 再输入(与用户「新开 google → 输入框填词」路径完全对齐),boot 门上限扩到 15s。部署三节点(版本戳 20261104.1240)。
5. **复测仍 0 结果** —— 回家门在位、提交链通,Google 依旧 302→/sorry:剩余根因收敛于 **impersonate MITM 链对 document 导航请求的 HTTP/2/TLS 帧特征(h2fp 的 SETTINGS/伪头序/TLS preset chrome 与 Chrome 146 不匹配)**。同一链路 pagefetch(XHR 类)如常 0.9~1.7s organic,而 document(GET)一击即中 —— Google 对 document GET 的 JS/一致性门更严。**待修专项:Chrome 146 帧级对齐 h2fp(与上述直连 typed 字同步联动验证)。**
пери压测余量与守卫机制不受影响;搜流量主体照旧 pagefetch 健康;typed 兜底环节在 h2fp 对齐完成前保持现状。
## 7. 极限压测 + 全节点温池化(2026-11-04,node 0.48.0 / admin 1.80.0)
**用户定稿:ETH-33 旧 veil 池架构经常死机(实测 10-24~11-03 五崩四次,11-03 xlp 灰度后稳定);测新架构极限,系统资源保留 20% 保证不死机;全部节点切温池,全部 SERP 请求走温池路径。**
### 7.1 节点资源守卫(node 0.48.0,git f50a13f)
- `src/core/system/resource.guard.ts`:可用内存(MemTotal-MemAvailable)< 20% 或 load1/核心数 > 80% ⇒ 拒绝**新预热**(SERP_POOL_FULL 语义,admin 补池 15s 重试自愈);池内 ready/busy 与进行中搜索不动。配置 `node-settings.json` 的 `resourceGuard` 键(admin /nodes 可视化编辑,1.80.0)+ `RESOURCE_GUARD_ENABLED=0` 逃生口;判定用 load1(load5 衰减太慢会压着守卫十几分钟)。失败读数不阻塞(降级语义)。
- /serp/pool 响应即带 guard 水位;metrics 新增 mem_free_pct / system_load_pct / serp_pool_guard_rejections_total;`resource.guard.test.ts` 5 用例(bun test 190 全过)。
- xLightpanda 端口扫描数可配 `XLIGHTPANDA_PORT_COUNT`(默认 64 → 压测时可放更深)。
### 7.2 ETH-33 极限压测数据(12 核 / 64G,守卫版压测)
| 档位 | 池态 | lightpanda 总 RSS(≈单实例) | 内存可用 | 稳态 load1 | 结论 |
|---|---|---|---|---|---|
| 64 | 64/64 ready | 6.1G(95MB) | 82-89% | ~0.2(闲) | 资源余量极大 |
| 96 | 96/96 ready | 8.6G(88MB) | 85.6% | ~0.2(闲) | 同上 |
| 128 | 128/128 ready | 11.7G(91MB) | 82% | ~0.04(闲) | 内存仍远未到保留线 |
- **机器资源极限远未到**:128 深池内存只占 18%,闲时 CPU≈0;负载尖峰(ll 12-19)全部来自共租任务(保活 veil 浏览器 churn、重启风暴),守卫在尖峰窗口正确拒绝增容、尖峰过后(分钟级)自动恢复补池——“保留 20% 保证不死机”机制实测有效。
- **真正的瓶颈是 Google 每 IP 会话配额**:ETH-33 全部 ~10k Profile 只绑 3 个上游代理 IP。池深 20(≈7 会话/IP)时搜索 0.9-1.7s 正常;128 深突发(43 会话/IP + 6 分钟 128 连发)后单实例首搜即 302→/sorry,5 分钟未恢复。**操作定值:ETH-33 池收在 64(≈21/IP)**;曾冲到 128 的会话密度待 IP 冷却后另行评估。
- 压测期间 admin 补池 15s×4/轮,自 0 填满 128 仅 ~7 分钟(重启风暴窗口守卫会自动压住几分钟后恢复)。
### 7.3 全节点温池化(2026-11-04 16:xx 前)
| 节点 | SERP_POOL_SIZE | admin override | 状态 |
|---|---|---|---|
| OVH-ETH-33 | 64 | 64 | xlightpanda,64/64 回填完成 |
| HZ-DE-245 | 50 | 50 | xlightpanda(原 veil 兜底),回填中 |
| OVH-DEDI-KS5B | 80 | 80 | xlightpanda(原 veil 兜底),回填中 |
- 服务名:ETH/HZ=serpmax-node(/opt/serpmax),KS5B=profilemax-node(/opt/profilemax);统一 WorkingDirectory=/app;三节点 /app/version=20261104.1300(/system/version 显示之)。
- admin serpConfig `fetchPerSec: 1→0`:令牌桶永不放行 go-fetch,**SERP 请求 100% 走浏览器温池**(go-fetch 代码保留;回滚 = 改回正数即可)。依据:错误请求集中于 go-fetch 直连路径,温池路径无此问题(用户 2026-11-04 定稿)。
- Storage Hook 三节点保持 enabled(合并写修复后 /system/dirs 保存不再覆盖 storageHook 块);资源守卫全部默认开启(20/20)。
- 回滚:节点删 node.env 的 SERP_BROWSER_KIND 行重启即回 veil/cloak 温池。
### 7.4 admin 1.80.0(git 07f696c)
- /api/nodes/:name/settings(中继节点 GET /system/dirs)+ PUT /api/nodes/:name 支持 storageHook/resourceGuard(undefined=不动/null=恢复默认/对象=合并下发)。
- /nodes 编辑弹窗新增「Storage Hook(缓存路由 tmpfs)」与「资源守卫(温池准入)」设置区,打开即回显节点现值;节点 /system/dirs 增加 GET,保存按顶层键合并(修复只改目录导致手配 storageHook 被抿掉的隐患)。前端已构建,profilemax-admin 已重启。
(注:守卫与 Hook 值均为节点侧即读即生效,保存无需重启。)