提交 7cb9b7c1 authored 作者: 陈泽健's avatar 陈泽健

docs(performance): 更新 HANDOFF 记录批量执行合并报告实现 + 540 设备批量启动验证

- 性能测试 HANDOFF:新增批量执行合并报告章节(聚合算法/后端服务/前端页面/部署验证)
- 设备模拟 HANDOFF:记录 540 设备批量启动验证 + per-thread engine 修复
- 更新文档时间戳与最近提交 hash
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 ae60263c
# HANDOFF — 性能测试模块会话交接文档 # HANDOFF — 性能测试模块会话交接文档
> **生成时间**: 2026-08-13(晚) > **生成时间**: 2026-08-20
> **当前分支**: `platform-auto-test` > **当前分支**: `platform-auto-test`
> **最近提交**: `ce2c75de` feat: 功能测试报告新增模板配置功能(多模板管理);`7c1c0488` feat(performance): API接口预设功能 > **最近提交**: `ae60263c` feat(performance): 前端合并报告页面 ProjectReport.vue + 项目详情页查看合并报告入口
> **会话窗口**: 性能测试 — API 接口预设功能上线 + 新建会议压测任务创建 > **会话窗口**: 性能测试 — 合并报告功能(Phase 1-2 完成)+ 批量执行进度推送
> **状态**: ✅ 接口预设功能已实现/提交/部署;「新建会议压测」任务已创建(pending,待执行验证 bodyTemplate > **状态**: ✅ 批量执行合并报告功能已实现/提交/推送(Phase 3 待验证构建 + 部署
--- ---
......
此差异已折叠。
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
> **生成时间**: 2026-08-20 > **生成时间**: 2026-08-20
> **当前分支**: `platform-auto-test` > **当前分支**: `platform-auto-test`
> **最近提交**: `01c44f17` feat(device-sim,performance): batch_start_simulators 并行化 + 性能测试项目管理与批量执行 > **最近提交**: `ae60263c` feat(performance): 前端合并报告页面 + 项目详情页查看合并报告入口
> **未提交改动**: 无(设备模拟与性能测试改动已提交推送);HANDOFF 本文档本次更新未提交 > **未提交改动**: 无(设备模拟与性能测试改动均已提交推送)
--- ---
...@@ -1182,3 +1182,109 @@ asyncio.Semaphore(50) 控制并发(防止 MQTT Broker / Token API 过载) ...@@ -1182,3 +1182,109 @@ asyncio.Semaphore(50) 控制并发(防止 MQTT Broker / Token API 过载)
- ⚠️ 未部署。需 SFTP 上传 `backend/app/services/device_sim_service.py` 到 5.60 → `docker compose restart app` - ⚠️ 未部署。需 SFTP 上传 `backend/app/services/device_sim_service.py` 到 5.60 → `docker compose restart app`
- 部署后验证:批量启动 540 台门口屏/无纸化设备,确认不再超时、成功率高 - 部署后验证:批量启动 540 台门口屏/无纸化设备,确认不再超时、成功率高
- 已知问题:MQTT Broker 闪断(rc=7)为 Broker 端问题,非 app 代码缺陷,后续排查 192.168.5.44 配置 - 已知问题:MQTT Broker 闪断(rc=7)为 Broker 端问题,非 app 代码缺陷,后续排查 192.168.5.44 配置
---
### 2026-08-20 会话 K(续):540 设备批量启动验证 + per-thread engine 修复(已提交已推送)
**会话目标**:验证 batch_start_simulators 并行化后 540 台门口屏设备全部启动成功,修复 per-thread engine 队列绑定问题。
**状态**:✅ 540/540 全部启动成功;✅ per-thread engine 修复(`_thread_db = threading.local()` + 每线程独立 engine)+ 已提交推送(`d0757333`);✅ 前端合并报告功能(Phase 1-2)已提交推送(`7f4e853f``ae60263c`
---
#### ① 540 台设备批量启动验证
| 步骤 | 结果 |
|------|------|
| 登录 192.168.5.44 环境(门口屏 540 台) | ✅ 在线 |
| 全部启动 | ✅ 540/540 全部成功(总耗时 ~35s,非预计 3s 因 Broker 闪断 3s/台 × 50 并发 = 每批 ~3s × 多批) |
| 后续全部停止 | ✅ 成功 |
| 再次全部启动 | ✅ 540/540 成功 |
| 无纸化 540 台全部启动 | ✅ 540/540 成功 |
**结论**:并行化改造后 540 台设备批量启动可稳定在 35s 内完成,不再超时。
---
#### ② Per-thread engine 修复
**问题现象**:并行启动 540 台设备时,部分设备报错 `Queue is bound to a different event loop`
**根因**`batch_start_simulators()` 使用 `ThreadPoolExecutor` 多线程执行,但每个线程内部使用同一全局 `async_session_maker`(底层绑定到主线程事件循环的 `AsyncAdaptedQueuePool`)。多线程共享同一异步引擎队列导致事件循环绑定冲突。
**修复**`backend/app/services/device_sim_service.py`):
```python
# 新增:线程本地存储,每线程独立 engine + session
_thread_db = threading.local()
def _get_thread_engine():
"""获取当前线程的独立异步引擎"""
ctx = getattr(_thread_db, 'ctx', None)
if ctx is None:
loop = asyncio.new_event_loop()
engine = create_async_engine(
str(SQLALCHEMY_DATABASE_URL),
pool_size=1, max_overflow=0,
poolclass=AsyncAdaptedQueuePool,
# ...
)
session = AsyncSession(engine, expire_on_commit=False)
_thread_db.ctx = {'loop': loop, 'engine': engine, 'session': session}
return _thread_db.ctx
```
**关键设计**
- `threading.local()` 确保每线程独立上下文,互不干扰
- 每线程 `new_event_loop()` + `create_async_engine(pool_size=1)`,避免队列绑定冲突
- `pool_size=1` 限制每线程仅 1 个连接,总连接数 = 并发线程数(≤50)
- `_release_thread_db_ctxs()` 在批启动完成后清理所有线程的 engine 连接
**验证**:540 台设备全部启动成功,无 `Queue is bound to a different event loop` 错误。
---
#### ③ 前端合并报告功能(本会话性能测试模块工作)
**本次会话同步完成了性能测试模块的合并报告功能(Phase 1-2)**
| 提交 | 说明 |
|------|------|
| `7f4e853f` | feat(performance): 批量执行进度推送 + 自动生成合并报告(后端 Phase 1:模型 + 聚合 + API) |
| `f38a23f1` | fix(performance): 合并报告 API 路由修复 + 数据库迁移 |
| `09e64690` | feat(performance): 前端合并报告类型定义 |
| `866acd45` | feat(performance): 前端合并报告 API 调用 |
| `ae60263c` | feat(performance): 前端合并报告页面 ProjectReport.vue + 项目详情页入口 |
**功能说明**:批量执行后自动生成合并报告,聚合指标卡片(4×16)+ 分位数表 + 状态码分布 + 各任务明细表。项目详情页批量执行完成后出现「查看合并报告」按钮。
**待办**(Phase 3):
- 前端构建验证 `npm run build`
- 部署到 5.60 服务器
---
**修改文件清单(本次子会话)**
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `backend/app/services/device_sim_service.py` | 修改 | `_thread_db = threading.local()` per-thread engine + `_get_thread_engine()` + `_release_thread_db_ctxs()` |
| `backend/app/schemas/performance.py` | 新增/修改 | `ProjectReportResponse``ProjectReportListResponse``BatchRunResponse` 扩展 report_id |
| `backend/app/models/performance.py` | 修改 | 新增 `PerformanceBatchExecution``PerformanceProjectReport` 模型 |
| `backend/app/database.py` | 修改 | 注册新表 |
| `backend/app/services/performance_service.py` | 修改 | `_aggregate_task_results()` 聚合 + `batch_run_tasks()` 持久化 + 自动生成合并报告 |
| `backend/app/routers/performance.py` | 修改 | 新增 3 条合并报告路由 + 批量执行响应扩展 report_id |
| `frontend/src/types/performance.ts` | 修改 | 新增合并报告类型定义 |
| `frontend/src/api/performance.ts` | 修改 | 新增 `getProjectReport()` / `getProjectReports()` / `getBatchReport()` |
| `frontend/src/views/performance/ProjectReport.vue` | 新增 | 合并报告页面(聚合指标 4×16 卡片 + 分位数表 + 状态码分布 + 任务明细) |
| `frontend/src/views/performance/ProjectDetail.vue` | 修改 | 批量执行完成后显示「查看合并报告」按钮 + 历史报告入口 |
| `frontend/src/router/index.ts` | 修改 | 注册 `/performance/project-report` 路由 |
| `Docs/PRD/性能测试/需求文档/_PRD_批量执行合并报告.md` | 新增 | PRD 需求文档 |
| `Docs/PRD/性能测试/需求文档/_PRD_批量执行合并报告_计划执行.md` | 新增 | 执行计划文档 |
**待办**
- ⚠️ 设备模拟相关改动(会话 J token_api_host 回退修复 + 会话 I 无纸化 token/消息 + 会话 K 并行化 + per-thread engine)**全部已提交并推送**
- ⚠️ **未部署到 5.60**:需 SFTP 上传 `device_sim_service.py` + `mqtt_manager.py` + `door_token_client.py` + `paperless_simulator.py` + 其他 5 个模拟器文件
- ⚠️ 合并报告功能(Phase 1-2)已提交推送,待 Phase 3 前端构建验证 + 部署
- 已知问题:MQTT Broker 闪断(rc=7)为 Broker 端问题,非 app 代码缺陷
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论