# 2026-04-16 Admin2 蜘蛛预览正式服排障记录 ## 背景 本次排障发生在正式服管理端 `https://admin2.jpjdxs.info/`。 用户反馈的问题分为三个阶段: 1. 管理端请求蜘蛛工作台接口时报 CORS 错误。 2. 前端在处理临时产物和缓存后,首页出现运行时异常,页面加载不稳定。 3. 页面恢复后,点击“蜘蛛预览”接口返回 `500`。 本次工作定位为正式服辅助分析、止血、优化与修复,开发主线仍由主 Codex 继续维护。 ## 最终结论 这次问题不是单点故障,而是三层问题叠加: 1. 前端生产环境接口地址指向了跨域域名,导致浏览器先出现 CORS 报错。 2. 排障过程中过的脏 `dist` 与浏览器 `Service Worker` 缓存叠加,导致首页运行时异常。 3. 蜘蛛工作台接口在 24 小时窗口下同步聚合过多抓取摘要文件,触发 PHP 128MB 内存上限,最终返回 `500`。 ## 线上现象 ### 1. CORS 阶段 浏览器最初报错: - 管理端来源:`https://admin2.jpjdxs.info` - 被请求接口:`https://adapi.ra12.shop/site/domain/spider-crawl/workbench/summary?...` - 浏览器错误:`No 'Access-Control-Allow-Origin' header is present on the requested resource` ### 2. 前端运行时阶段 首页曾出现运行时异常: - `TypeError: Cannot read properties of null (reading 'nextSibling')` 这个阶段和手工改动过的前端产物以及旧缓存有关,不是蜘蛛工作台业务逻辑本身的问题。 ### 3. 蜘蛛预览 500 阶段 页面恢复后,点击蜘蛛预览再次报错: - 请求地址: - `/api/site/domain/spider-crawl/workbench/summary?run_limit=10&anomaly_limit=80&window_hours=24&bot_scope=all&selected_bots=baiduspider,sogou` - 浏览器错误: - `AxiosError: Request failed with status code 500` ## 根因定位 ### 根因一:前端生产环境接口配置为跨域域名 正式服前端原先在生产环境里直接请求外部域名,浏览器因此走了跨域模式。 关联文件: - `VideoAdminV2/.env.production` 修复思路: - 将前端生产环境接口基址改为同源 `/api` - 由管理端 nginx 反向代理到后端服务 ### 根因二:旧 `Service Worker` 与临时修改产物污染 在排障期间,浏览器端同时受到以下因素影响: - 旧 `Service Worker` 缓存 - 旧静态资源哈希 - 临时手工调整过的 `dist` 这会导致首页有机会出现和真实源码不一致的运行时行为。 修复思路: - 用 `nvm` 环境重新构建干净前端产物 - 关闭 PWA,避免继续注册新的 `Service Worker` - 首页增加旧缓存清理逻辑 - 首页增加 `localStorage` 解析容错 ### 根因三:蜘蛛工作台同步聚合过多摘要文件导致 PHP 内存耗尽 这是点击“蜘蛛预览”时 `500` 的真实根因。 日志证据来自: - `/www/wwwlogs/source.video2.com.error.log` 关键错误: - `Allowed memory size of 134217728 bytes exhausted` - 涉及文件: - `/www/wwwroot/VideoSource2/code/app/common/helper/DomainSpiderCrawlWorkbenchHelper.php` - `/www/wwwroot/VideoSource2/code/app/common/helper/DomainSpiderCrawlLogHelper.php` 当时请求示例: - `GET /site/domain/spider-crawl/workbench/summary?run_limit=10&anomaly_limit=80&window_hours=24&bot_scope=all&selected_bots=baiduspider,sogou` 触发原因: - `window_hours=24` 时会扫描大量 `crawl-logs.summary.json` - 旧实现会把多份 summary 读入内存后进行聚合 - 正式服数据量明显大于开发环境 排障时观察到的数据规模: - `storage/domain-spider-crawl/runs` 目录约 `47M` - `crawl-logs.summary.json` 数量约 `154` 份 - 单个摘要文件最大接近 `958507` bytes ## 已执行的修复 ### 一、管理端同源代理与 CORS 调整 #### 1. 管理端 nginx 增加 `/api/` 反向代理 文件: - `/www/server/panel/vhost/nginx/admin2.jpjdxs.info.conf` 处理效果: - 管理端改为访问同源 `/api/...` - 管理端不再直接跨域请求 `adapi.ra12.shop` #### 2. 后端 CORS 头调整 文件: - `/www/wwwroot/VideoSource2/code/app/admin/middleware/AdminCors.php` 处理效果: - 补齐允许方法 - 补齐允许头 - 增加 `Vary: Origin` ## 二、前端正式服止血 ### 1. 前端生产环境改为同源接口 文件: - `/www/wwwroot/VideoAdminV2/.env.production` 关键配置: - `VITE_API_URL=/api` - `VITE_PWA=false` ### 2. 首页增加容错和旧缓存清理 文件: - `/www/wwwroot/VideoAdminV2/index.html` 处理内容: - `IOMS-global` 的 `localStorage` 读取加 `try/catch` - 启动时注销旧 `serviceWorker` - 清理旧缓存 ### 3. 清理不再需要的启动期缓存逻辑 文件: - `/www/wwwroot/VideoAdminV2/src/main.ts` 处理内容: - 去掉启动时全量清理缓存的临时逻辑,避免继续引入不确定性 ### 4. 使用 `nvm` 环境重新构建前端 确认到正式服 `nvm` 环境为: - Node: `v20.19.6` - npm: `10.8.2` 实际使用命令: ```bash export HOME=/home/www export NVM_DIR="$HOME/.nvm" . "$NVM_DIR/nvm.sh" cd /www/wwwroot/VideoAdminV2 nvm use 20 npm run build:pro ``` 构建后线上主包为: - `assets/js/index-23f333c2.js` ## 三、蜘蛛工作台 500 修复 核心修复文件: - `/www/wwwroot/VideoSource2/code/app/common/helper/DomainSpiderCrawlWorkbenchHelper.php` 处理内容: 1. 增加聚合 run 上限: - `MAX_AGGREGATE_RUNS = 12` 2. `collectRunEntries()` 不再保存整份 summary 内容,只保存: - `summary_path` - `normalized` - `generated_at_ts` 3. `aggregateRunSummaries()` 改为按需读取文件,而不是提前把所有 summary 常驻内存 4. `buildSummary()` 在窗口聚合前先裁剪最近 run 5. `buildWindowComparison()` 也在聚合前先裁剪最近 run 这次修复的目标是正式服止血,不是最终态架构优化。 ## 验证结果 ### 1. 前端接口基址 已确认前端主包中接口基址为: - `baseURL:"/api"` ### 2. CORS 头 已确认响应头包含: - `Access-Control-Allow-Origin: https://admin2.jpjdxs.info` - `Vary: Origin` ### 3. helper 在 128MB 内存下可跑通 排障时在本机使用命令验证: ```bash php -d memory_limit=128M -r '... DomainSpiderCrawlWorkbenchHelper::buildSummary(...) ...' ``` 修复后返回正常,说明核心内存问题已被压住。 ### 4. PHP-FPM 已重载 执行: ```bash service php-fpm-83 reload ``` 用于确保线上 PHP 进程加载到修复后的 helper 代码。 ### 5. 用户回归验证 用户最终反馈: - “好了终于跑通了” 说明这次正式服问题已经完成闭环。 ## 对主 Codex 的交接建议 这次修复属于正式服止血方案,主 Codex 后续建议继续做结构化优化: 1. 不要在在线接口里同步扫描过多 run 文件。 2. 将蜘蛛工作台改造成预聚合模型,而不是请求时全量聚合。 3. 将 `1h / 6h / 24h / 72h` 窗口统计结果提前固化为摘要文件或缓存。 4. 为大窗口查询增加更清晰的降级策略与上限说明。 5. 如果后续还要放大统计维度,应考虑异步任务或离线聚合,不要继续依赖同步 `json_decode(file_get_contents(...))` 全量加载。 ## 本次涉及文件 前端相关: - `/www/wwwroot/VideoAdminV2/.env.production` - `/www/wwwroot/VideoAdminV2/index.html` - `/www/wwwroot/VideoAdminV2/src/main.ts` - `/www/server/panel/vhost/nginx/admin2.jpjdxs.info.conf` 后端相关: - `/www/wwwroot/VideoSource2/code/app/admin/middleware/AdminCors.php` - `/www/wwwroot/VideoSource2/code/app/common/helper/DomainSpiderCrawlWorkbenchHelper.php` 文档落点: - `/www/wwwroot/VideoSource2/docs/2026-04-16-admin2-spider-workbench-production-fix.md`