# PRD - 执行机资源监控（Load Generator Resource Monitoring）

> **文档版本**: v1.0
> **创建日期**: 2026-08-21
> **模块类型**: 性能测试 - 执行机资源监控
> **优先级**: P1
> **关联 PRD**: `_PRD_性能测试模块需求文档.md`

---

## 一、背景与目标

### 1.1 背景

性能测试结果的**可信度**依赖于执行环境：如果压测引擎所在机器（执行机/压测机）自身资源已耗尽（CPU 100%、内存不足、网络带宽打满），那么测得的 TPS 和响应时间反映的是**执行机瓶颈**而非被测系统性能，直接导致误判。

当前性能测试模块只采集**被测接口**的指标（TPS、响应时间等），完全没有采集执行机自身的资源指标。JMeter 等专业工具通过 PerfMon 插件（ServerAgent）监控负载机资源，本平台需要补齐这一能力。

### 1.2 目标

1. **执行机资源采集**：在压测执行期间定时采集执行机的 CPU、内存、网络 I/O 指标
2. **实时推送**：通过 WebSocket 实时推送资源利用率，与 TPS 等指标同步展示
3. **趋势分析**：在报告页展示资源利用率随时间的变化曲线
4. **瓶颈辅助判断**：帮助判断压测结果是否受执行机资源限制
5. **零依赖原则**：使用 Python 标准库（psutil 可选，优先标准库实现），不引入 Agent 部署

---

## 二、功能范围

### 2.1 核心功能

| 功能 | 描述 | 优先级 |
|------|------|--------|
| CPU 使用率采集 | 整体 CPU 使用率（%）+ 每核使用率（可选） | P0 |
| 内存使用率采集 | 物理内存使用率（%）+ 已用/总量（MB） | P0 |
| 网络 I/O 采集 | 发送/接收速率（KB/s）+ 累计字节数 | P0 |
| 磁盘 I/O 采集（可选） | 磁盘读写速率（KB/s）| P2 |
| 采样周期 | 默认 1 秒（与现有快照频率一致） | P0 |
| WebSocket 实时推送 | 资源指标随快照一并推送 | P0 |
| 趋势图表 | 监控页 + 报告页趋势图 | P0 |
| 资源报警提示 | CPU/内存超过阈值时在监控页提示 | P1 |

### 2.2 采集指标清单

| 指标 | 单位 | 说明 | 来源 |
|------|------|------|------|
| cpu_percent | % | CPU 总使用率 | psutil / /proc（Linux）/ GetSystemTimes（Windows） |
| mem_percent | % | 物理内存使用率 | psutil.virtual_memory() |
| mem_used | MB | 已用内存 | 同上 |
| mem_total | MB | 总内存 | 同上 |
| net_sent_bytes | B | 累计发送字节（采样点值） | psutil.net_io_counters() |
| net_recv_bytes | B | 累计接收字节（采样点值） | 同上 |
| net_sent_kb_s | KB/s | 发送速率（周期内差值/采样间隔） | 差值计算 |
| net_recv_kb_s | KB/s | 接收速率（周期内差值/采样间隔） | 差值计算 |
| process_cpu_percent | % | 压测进程自身 CPU（可选） | 进程句柄 |
| process_mem_mb | MB | 压测进程自身内存（可选） | 进程句柄 |
| disk_read_kb_s / disk_write_kb_s | KB/s | 磁盘读写速率（可选） | psutil.disk_io_counters() |

### 2.3 Windows 平台注意

执行机可能位于 Windows（本机开发）或 Linux（5.60 服务器部署）：

- **优先使用 psutil**：跨平台、成熟可靠。若服务器已安装则直接用
- **标准库兜底**：若 psutil 不可用，Linux 读取 `/proc/stat`、`/proc/meminfo`、`/proc/net/dev`；Windows 使用 `ctypes` 调 `GetSystemTimes` + `GlobalMemoryStatusEx` + `GetIfTable2`（网络 I/O）
- 实现独立模块 `ResourceMonitor`，psutil 可用时自动优先

---

## 三、详细需求

### 3.1 数据模型

#### 3.1.1 ResourceSnapshot（资源快照）

每采样周期一条，关联任务 ID：

```python
class ResourceSnapshot:
    task_id: str          # 关联任务ID
    timestamp: float      # 采集时间戳（秒）
    elapsed: float        # 距开始时间（秒）
    cpu_percent: float    # CPU 使用率（%）
    mem_percent: float    # 内存使用率（%）
    mem_used_mb: float    # 已用内存（MB）
    mem_total_mb: float   # 总内存（MB）
    net_sent_kb_s: float  # 发送速率（KB/s）
    net_recv_kb_s: float  # 接收速率（KB/s）
    net_sent_total_mb: float  # 累计发送（MB）
    net_recv_total_mb: float  # 累计接收（MB）
```

#### 3.1.2 存储方案

考虑到数据量与现有架构的简单性，采用**两种存储层次**：

| 层次 | 存储 | 说明 |
|------|------|------|
| 实时推送 | WebSocket，不落库 | 监控页实时显示用 |
| 历史报告 | performance_task 增加 `resource_summary` JSON 字段 | 存采样序列（首/尾/均值/最大值 + 全量序列，控制序列长度上限 3000 点） |

不新建独立 resource_snapshots 表（避免表数量膨胀），复用任务 JSON 字段。

### 3.2 采集模块设计

#### 3.2.1 ResourceMonitor 类

```python
class ResourceMonitor:
    """执行机资源监控器，每采样周期采集一次资源指标"""

    def __init__(self, sampling_interval: float = 1.0):
        self._interval = sampling_interval
        self._last_net = None      # 上次网络计数器
        self._last_ts = None       # 上次采样时间

    def sample(self) -> dict:
        """采集一次资源指标，返回 dict（含速率差值计算）"""

    def dispose(self):
        """释放资源"""
```

#### 3.2.2 集成方式

在 `PerformanceExecutor` 中与 `_snapshot_loop` 并行启动一个 `_resource_loop`：

```
PerformanceExecutor.execute()
├── _snapshot_loop（现有）：每秒采集请求指标 → 回调推送
└── _resource_loop（新增）：每秒采集资源指标 → 合并进同一个快照推送
```

推送合并策略：资源指标合并到现有 `performance_snapshot` 消息的 data 中（同频率、同频道），前端 `MonitorPanel` 直接读取新字段，无需新的 WebSocket 连接：

```json
{
  "type": "performance_snapshot",
  "task_id": "perf_xxx",
  "data": {
    "elapsed": 5.2,
    "tps": 123.45,
    "...": "...",
    "resource": {
      "cpuPercent": 45.2,
      "memPercent": 62.1,
      "netSentKbS": 10.5,
      "netRecvKbS": 88.3
    }
  }
}
```

### 3.3 实时监控页

在 `MonitorPanel.vue` 增加「执行机资源」区块：

#### 3.3.1 资源利用率卡片

| 卡片 | 显示内容 | 告警阈值 |
|------|---------|---------|
| CPU Usage（CPU 使用率） | 当前 CPU % + 迷你趋势 | > 85% 红色 |
| Memory Usage（内存使用率） | 当前内存 % + 已用/总量 | > 85% 红色 |
| Network Sent（网络发送） | 当前发送速率 KB/s | - |
| Network Received（网络接收） | 当前接收速率 KB/s | - |

#### 3.3.2 资源趋势图

- 「执行机资源趋势 Resource」组合图：
  - 上图：CPU % + 内存 % 双折线
  - 下图：网络发送/接收 KB/s 双折线
- 与 TPS 图共享时间轴（同 X 轴）

### 3.4 报告页

在 `ReportPanel.vue` 增加「执行机资源」区块：

- 资源汇总卡片：平均 CPU / 最大 CPU / 平均内存 / 最大内存 / 平均发送 / 平均接收
- 资源趋势图（同监控页）
- 数据来源：`resource_summary` JSON 字段（无资源数据时该区块隐藏）

### 3.5 批量监控页

在 `BatchMonitor.vue` 增加类似监控页的资源区块（当前选中任务维度的资源曲线）。

### 3.6 后端配置

```yaml
# config.py 新增
RESOURCE_MONITOR_ENABLED: bool = True      # 是否开启执行机资源监控
RESOURCE_MONITOR_INTERVAL: float = 1.0     # 采样间隔（秒）
RESOURCE_ALERT_CPU: float = 85.0           # CPU 告警阈值（%）
RESOURCE_ALERT_MEM: float = 85.0           # 内存告警阈值（%）
```

---

## 四、非功能需求

| 项 | 要求 |
|----|------|
| 采集开销 | 单次采样 < 5ms（psutil），不影响压测引擎 |
| 采样频率 | 默认 1 秒，可配置 |
| 兼容性 | Windows / Linux 双平台；psutil 缺失时标准库兜底 |
| 数据量控制 | resource_summary 序列上限 3000 点，超出后降采样（每 2 点取 1） |

---

## 五、现有资产复用与对比

### 5.1 资产复用

| 现有资产 | 用途 |
|---------|------|
| `_snapshot_loop` | 定时采样框架复用（资源循环并行） |
| WebSocket Manager | 快照推送通道（增加 resource 字段） |
| `MonitorPanel.vue` ECharts 组件 | 趋势图渲染框架复用 |
| `ReportPanel.vue` | 报告区块复用 |

### 5.2 与 JMeter PerfMon 对比

| 维度 | JMeter + PerfMon | 本方案 |
|------|------------------|--------|
| Agent 部署 | 每台负载机需部署 ServerAgent | 零部署，进程内采集 |
| 指标范围 | CPU/内存/磁盘/网络 | 同（磁盘可选） |
| 采样方式 | UDP 采样 | 进程内定时采样 |
| 集成度 | 插件单独配置 | 与快照推送天然合并 |

---

## 六、风险与缓解

| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| psutil 未安装 | 采集失败 | 标准库兜底实现 /proc 与 Windows API |
| 采样本开销干扰压测 | 极小 | 采样间隔 1s 且开销 <5ms，实测验证 |
| 高并发下采样数据量大 | WebSocket 带宽占用 | 资源数据仅 4 个核心字段随快照推送 |
| 采集进程即执行进程，无法区分 | 资源值包含引擎自身开销 | 可选记录 process_cpu 供对比分析 |

---

## 七、附录

### 7.1 数据流

```
ResourceMonitor 每秒采样
    ├── CPU /proc 或 psutil
    ├── 内存 /proc 或 psutil
    └── 网络计数器差值
        ↓
合并进 performance_snapshot 消息 (data.resource)
        ↓
WebSocket 推送给前端
    ├── MonitorPanel 实时卡片 + 趋势图
    └── BatchMonitor 选中任务资源曲线
        ↓
执行结束 → resource_summary 写入任务 JSON 字段
        ↓
ReportPanel 报告页资源区块
```

### 7.2 后端 API 变更

| 接口 | 变更 | 说明 |
|------|------|------|
| GET /api/performance/report/{taskId} | 扩展 | 响应增加 resourceSummary 字段 |

### 7.3 前端 API/类型变更

| 文件 | 变更 |
|------|------|
| `frontend/src/types/performance.ts` | PerformanceSnapshot 增加 resource 字段；Report 增加 resourceSummary |
| `frontend/src/views/performance/MonitorPanel.vue` | 资源卡片 + 资源趋势图 |
| `frontend/src/views/performance/ReportPanel.vue` | 资源汇总 + 资源趋势图 |
| `frontend/src/views/performance/BatchMonitor.vue` | 资源趋势图 |

---

*本文档为执行机资源监控功能的需求定义，后续将输出计划执行文档用于指导开发。*