103 lines
3.9 KiB
Markdown
103 lines
3.9 KiB
Markdown
|
|
# Changelog — 脚本批量执行平台(完整交付)
|
|||
|
|
|
|||
|
|
**日期**: 2026-05-22
|
|||
|
|
**类型**: 功能 / 架构
|
|||
|
|
**SSOT**: `docs/project/script-execution.md`
|
|||
|
|
|
|||
|
|
## 变更摘要
|
|||
|
|
|
|||
|
|
在原有「脚本库 + 单批 exec」基础上,交付**生产级批量执行平台**:
|
|||
|
|
|
|||
|
|
1. **内置分批** — 超 50 台自动多批 `POST /exec`,前端合并为一条状态卡(见 `2026-05-22-script-exec-batching.md`)
|
|||
|
|
2. **长任务** — nohup + 子机 curl 回调 + 页顶状态 / 远程 tail 日志(见 `2026-05-22-script-job-callback.md`)
|
|||
|
|
3. **Redis 热路径 + MySQL 分批落库** — 减轻 DB;读优先 Redis
|
|||
|
|
4. **短任务可停止** — Agent `/exec` + `/exec/wait` + `/exec/kill`
|
|||
|
|
5. **执行历史页** — 列表、进度、操作按钮、自动刷新
|
|||
|
|
6. **卡住治理** — 人工标记 + 单台/整单自动检测 + 审计
|
|||
|
|
|
|||
|
|
## 背景与决策
|
|||
|
|
|
|||
|
|
| 决策 | 选择 | 原因 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 进度查询 | JWT 轮询 `GET /executions/{id}` | 用户明确不要 WS 换票、不要独立 async exec API |
|
|||
|
|
| 执行态存储 | Redis 2h TTL | 前端实时;MySQL 只存历史 |
|
|||
|
|
| MySQL 写入 | 60s 批量最多 50 条 | 降低写压力;审计仍即时 |
|
|||
|
|
| 卡住阈值等 | 代码常量 | 用户要求不写 `.env` |
|
|||
|
|
| 分批大小 | `.env` 可配 | 与安装向导/运维调优一致 |
|
|||
|
|
|
|||
|
|
## 数据流(简图)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
POST /exec → ScriptService → Redis(script_exec:id) → 前端轮询
|
|||
|
|
↓ Agent (短/长)
|
|||
|
|
长任务结束 → curl → /api/agent/script-callback → Redis 更新
|
|||
|
|
每 60s → script_execution_flush → MySQL script_executions
|
|||
|
|
audit_logs ← 即时写入(各操作 action)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## API 与页面(新增/扩展)
|
|||
|
|
|
|||
|
|
| 类型 | 项 |
|
|||
|
|
|------|-----|
|
|||
|
|
| API | `GET /scripts/executions`, `GET .../{id}?fetch_logs=`, `POST .../stop`, `retry`, `mark-stuck`, `POST /agent/script-callback` |
|
|||
|
|
| 页面 | `web/app/script-executions.html` |
|
|||
|
|
| 页面增强 | `scripts.html` 页顶状态条、执行历史入口;`audit.html` 脚本 action 筛选 |
|
|||
|
|
| Agent | `web/agent/agent.py` — `/exec` wait 参数、`/exec/wait`、`/exec/kill` |
|
|||
|
|
| 后台 | `server/background/script_execution_flush.py` |
|
|||
|
|
|
|||
|
|
## 涉及文件
|
|||
|
|
|
|||
|
|
### 新增
|
|||
|
|
|
|||
|
|
| 文件 |
|
|||
|
|
|------|
|
|||
|
|
| `server/infrastructure/redis/script_execution_store.py` |
|
|||
|
|
| `server/background/script_execution_flush.py` |
|
|||
|
|
| `server/application/services/script_jobs.py` |
|
|||
|
|
| `server/application/services/script_job_callback.py` |
|
|||
|
|
| `web/app/script-executions.html` |
|
|||
|
|
| `docs/project/script-execution.md` |
|
|||
|
|
| `docs/changelog/2026-05-22-script-execution-platform.md` |
|
|||
|
|
|
|||
|
|
### 修改
|
|||
|
|
|
|||
|
|
| 文件 | 要点 |
|
|||
|
|
|------|------|
|
|||
|
|
| `server/application/services/script_service.py` | 分批、长/短任务、stop/retry/list、Agent kill |
|
|||
|
|
| `server/api/scripts.py` | executions 路由 |
|
|||
|
|
| `server/api/agent.py` | script-callback |
|
|||
|
|
| `server/infrastructure/database/script_repo.py` | `list_recent` |
|
|||
|
|
| `server/main.py` | 注册 flush loop |
|
|||
|
|
| `server/config.py` | `SCRIPT_EXEC_*` |
|
|||
|
|
| `web/app/scripts.html` | 状态条、分批、长任务 |
|
|||
|
|
| `web/app/layout.js` | 执行历史菜单 |
|
|||
|
|
| `web/app/audit.html` | action 筛选 |
|
|||
|
|
| `web/agent/agent.py` | exec/wait/kill |
|
|||
|
|
|
|||
|
|
## 配置
|
|||
|
|
|
|||
|
|
| 项 | 位置 | 默认 |
|
|||
|
|
|----|------|------|
|
|||
|
|
| `NEXUS_SCRIPT_EXEC_BATCH_SIZE` | `.env` / `config.py` | 50 |
|
|||
|
|
| `NEXUS_SCRIPT_EXEC_CONCURRENCY` | `.env` / `config.py` | 10 |
|
|||
|
|
| `NEXUS_API_BASE_URL` | `.env` | 长任务必填 |
|
|||
|
|
| `REDIS_TTL_SECONDS` 等 | `script_execution_store.py` | 见 SSOT §1 |
|
|||
|
|
|
|||
|
|
## 部署注意
|
|||
|
|
|
|||
|
|
1. 主站重启后 `script_execution_flush` 随 primary worker 启动
|
|||
|
|
2. 子机需部署新版 `web/agent/agent.py` 才能短任务中途停止
|
|||
|
|
3. 长任务必须配置子机可访问的 `NEXUS_API_BASE_URL`
|
|||
|
|
|
|||
|
|
## 测试状态
|
|||
|
|
|
|||
|
|
| ID | 项 | 状态 |
|
|||
|
|
|----|-----|------|
|
|||
|
|
| T-SE1~T-SE8 | 见 `docs/project/script-execution.md` §11 | ⏳ 待 WSL/外网 |
|
|||
|
|
|
|||
|
|
## 关联文档
|
|||
|
|
|
|||
|
|
- 技术 SSOT: `docs/project/script-execution.md`
|
|||
|
|
- 分批: `docs/changelog/2026-05-22-script-exec-batching.md`
|
|||
|
|
- 回调与 Redis: `docs/changelog/2026-05-22-script-job-callback.md`
|