# OPS P1 故障救援策略

## 1. 文档目标

本文定义第 1 阶段必须覆盖的平台自身故障处理策略，重点解决采集失败、Trap/Syslog 解析失败、通知失败和派单失败不能静默的问题。

本文用于指导 `server/internal/logic/`、`server/internal/models/`、`web/src/views/` 和验收脚本实现。相关状态机以 `docs/首期数据模型与状态机.md` 为准。

## 2. 通用原则

| 原则 | 要求 |
| --- | --- |
| 错误可见 | 平台内部失败必须进入可查询记录，不允许只写进控制台日志。 |
| 业务不中断 | 通知失败、自动派单失败不能阻断告警确认、人工派单和工单处理。 |
| 可重试 | 外部依赖、网络抖动、临时超时类错误必须支持自动重试和人工重试。 |
| 可降级 | 解析失败、通知失败、派单失败要进入待处理队列或未解析池，而不是丢弃。 |
| 可审计 | 状态变化、重试、人工修正、规则重放必须写审计日志并带 `traceId`。 |
| 可测试 | 每一类救援路径都要有接口测试或端到端测试覆盖。 |

## 3. 统一错误分类

| 错误码 | 场景 | 用户提示 | 默认处理 |
| --- | --- | --- | --- |
| `COLLECT_UNREACHABLE` | 设备不可达、端口不通 | 设备不可达，保留最近成功采集时间 | 按策略重试，连续失败后生成平台内部事件 |
| `COLLECT_AUTH_FAILED` | 凭据错误、权限不足 | 凭据不可用，请检查凭据引用和设备权限 | 停止高频重试，提示人工修正 |
| `COLLECT_TIMEOUT` | SNMP、Agent、数据库、自定义 SQL 超时 | 采集超时，已进入重试队列 | 指数退避重试，标记采集延迟 |
| `EVENT_PARSE_FAILED` | Trap/Syslog 字典缺失或格式不匹配 | 事件未解析，可补充规则后重放 | 进入未解析事件池 |
| `NOTIFY_CHANNEL_FAILED` | 站内消息、短信、邮件发送失败 | 通知发送失败，不影响告警处理 | 按渠道重试，允许人工补发 |
| `TICKET_ASSIGN_FAILED` | 无匹配处理人、权限不足、重复派单 | 自动派单失败，请人工选择处理人 | 回退待分派状态 |
| `STATE_CONFLICT` | 并发确认、关闭、转交 | 状态已变化，请刷新后重试 | 拒绝本次操作并返回当前状态 |
| `RATE_LIMITED` | 告警风暴、通知过载 | 已限流，部分通知合并发送 | 启用限流和摘要通知 |

所有 API 错误响应必须包含 `code`、`message`、`traceId` 和 `suggestion`。

## 4. 采集失败救援

### 4.1 失败来源

| 来源 | 典型原因 | 是否自动重试 | 是否生成内部事件 |
| --- | --- | --- | --- |
| SNMP 轮询 | 设备不可达、团体字错误、OID 不支持 | 是 | 连续失败达到阈值后生成 |
| H3C/华三接口指标 | 接口索引变化、接口 down、设备重启 | 是 | 是 |
| 主机 Agent | Agent 离线、版本不兼容、主机防火墙 | 是 | 是 |
| 数据库监控 | 账号权限不足、SQL 超时、连接池耗尽 | 按错误类型 | 是 |
| URL/API 探测 | 5xx、超时、DNS 失败、证书失败 | 是 | 是 |

### 4.2 重试策略

| 错误类型 | 自动重试 | 退避策略 | 人工动作 |
| --- | --- | --- | --- |
| 网络不可达 | 3 次 | 30 秒、1 分钟、5 分钟 | 检查网络和防火墙 |
| 协议超时 | 3 次 | 10 秒、30 秒、1 分钟 | 调整超时或采集周期 |
| 凭据错误 | 0 次或 1 次确认 | 不持续重试 | 修改凭据引用 |
| 指标部分缺失 | 不重试整个任务 | 标记缺失指标 | 检查模板与设备型号 |
| 采集器异常 | 2 次 | 10 秒、30 秒 | 查看采集器日志 |

### 4.3 降级表现

- 资源列表显示 `collect_status=failed` 或 `partial_success`。
- 资源详情显示最近成功采集时间、失败原因和失败次数。
- 时序图只展示已有样本，并标记缺口时间段。
- 首页、大屏和报表显示“数据过期”或“部分指标不可用”，不使用假数据填充。

### 4.4 日志与审计

每次失败至少记录：

| 字段 | 说明 |
| --- | --- |
| `collector_task_id` | 采集任务 ID。 |
| `resource_id` | 资源 ID。 |
| `error_code` | 统一错误码。 |
| `error_message` | 原始失败摘要，敏感信息脱敏。 |
| `retry_count` | 当前重试次数。 |
| `last_success_at` | 最近成功采集时间。 |
| `trace_id` | 请求或任务链路 ID。 |

## 5. Trap/Syslog 解析失败救援

### 5.1 处理流程

```text
+-----------+      +-------------+      +----------------+
| 接收原文  | ---> | 写 raw_events | ---> | 尝试字典/规则解析 |
+-----------+      +-------------+      +----------------+
                                             |
                         +-------------------+-------------------+
                         v                                       v
                  +-------------+                         +--------------+
                  | parsed      |                         | unparsed     |
                  | 转告警或抑制 |                         | 待补规则重放 |
                  +-------------+                         +--------------+
```

### 5.2 未解析事件要求

| 项目 | 要求 |
| --- | --- |
| 入库 | 原始报文必须先写入 `raw_events.payload_json` 或原文存储字段。 |
| 状态 | `parse_status=unparsed`，不能直接删除。 |
| 可见性 | 告警中心或事件池显示未解析数量、来源、接收时间。 |
| 重放 | 补充 Trap 字典、OID 描述或 Syslog 规则后，可对选定事件重放解析。 |
| 审计 | 规则新增、规则修改、重放动作必须写审计。 |

### 5.3 用户提示

| 场景 | 页面提示 | 建议动作 |
| --- | --- | --- |
| OID 字典缺失 | 未识别 Trap OID | 补充 OID 描述和级别映射 |
| Syslog 格式不匹配 | 日志规则未命中 | 创建或调整解析规则 |
| 资源无法匹配 | 事件来源未绑定资源 | 绑定来源 IP、主机名或设备标识 |
| 恢复事件不完整 | 无法判断恢复关系 | 补充恢复规则或人工关闭 |

## 6. 通知失败救援

### 6.1 渠道策略

| 渠道 | 首期要求 | 失败处理 |
| --- | --- | --- |
| 站内消息 | 必须支持 | 写失败记录，允许重新发送 |
| 短信 | 必须支持测试账号 | 记录第三方返回码，按渠道限流 |
| 邮件 | 必须支持测试 SMTP | 记录 SMTP 错误摘要，支持人工补发 |

通知失败不改变告警和工单主状态。告警详情必须展示通知记录和失败原因。

### 6.2 重试与限流

| 场景 | 策略 |
| --- | --- |
| 临时网络失败 | 自动重试 3 次，间隔 1 分钟、5 分钟、15 分钟。 |
| 第三方限流 | 暂停该渠道，改为站内消息和摘要通知。 |
| 收件人无效 | 不自动重试，提示维护接收人配置。 |
| 告警风暴 | 同一资源同一规则在去重窗口内合并通知。 |
| 高级别告警 | 可突破普通限流，但仍要记录发送频率和接收人。 |

## 7. 派单失败救援

### 7.1 自动派单失败

| 失败原因 | 救援动作 | 用户可见表现 |
| --- | --- | --- |
| 无匹配处理人 | 回退为待分派，显示推荐处理组为空 | 告警详情显示“请选择处理人” |
| 处理人无权限 | 回退为待分派，提示权限不匹配 | 派单失败记录可见 |
| 重复派单 | 拒绝创建新未关闭工单，返回已有关联工单 | 告警详情跳转已有工单 |
| 工单状态冲突 | 拒绝更新，返回当前工单状态 | 页面提示刷新 |
| 规则配置错误 | 禁用该自动派单规则或标记异常 | 策略页显示异常规则 |

### 7.2 人工救援

- 告警详情提供“重新派单”和“手动创建工单”入口。
- 工单列表支持筛选 `source=dispatch_failed`。
- 派单规则异常必须出现在系统管理或策略页，不只存在于日志。

## 8. 测试要求

| 测试项 | 类型 | 通过标准 |
| --- | --- | --- |
| 采集凭据错误 | 后端接口测试 | 返回 `COLLECT_AUTH_FAILED`，资源采集状态失败，写审计。 |
| SNMP 超时 | 后端集成测试 | 触发重试，连续失败后生成内部事件。 |
| Trap 未解析 | 接口测试 | `raw_events` 保留原文，状态为 `unparsed`，补规则后可重放。 |
| 短信发送失败 | 集成测试 | 告警状态不变，通知记录失败，可人工补发。 |
| 自动派单无人匹配 | 端到端测试 | 告警保留待分派提示，不创建重复工单。 |
| 并发关闭工单 | 后端接口测试 | 只有一个请求成功，其余返回 `STATE_CONFLICT`。 |

## 9. 验收证据

| 证据 | 要求 |
| --- | --- |
| 接口响应 | 保留失败请求、错误码、`traceId` 和建议动作。 |
| 页面截图 | 资源详情、未解析事件池、通知记录、派单失败提示。 |
| 日志 | 能按 `traceId` 查询采集、解析、通知、派单链路。 |
| 数据库记录 | `collector_runs`、`raw_events`、`notification_records`、`ticket_transitions` 有对应记录。 |
