Files
Inbox/系统基座文件/2/2.3/2.3.4 故障传播与恢复信令 (Fault Propagation & Recovery Signaling).md
2025-12-11 07:24:36 +08:00

123 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
tags: []
date created: 星期五, 十一月 21日 2025, 3:14:02 下午
date modified: 星期一, 十一月 24日 2025, 4:31:32 下午
---
# 2.3.4 故障传播与恢复信令 (Fault Propagation & Recovery Signaling)
这是系统的“求救与自愈”机制。在 2.3.3 中,我们定义了正常的生老病死;而 2.3.4 则要定义当模块“意外暴毙”时,系统如何避免全面崩溃,并有序地重新站起来。
特别需要注意的是,根据您的 **附件:生产环境架构加固指南**,我们引入了父进程 Watchdog。因此本节的故障处理必须划清界限**逻辑故障归调度器管,进程崩溃归 Watchdog 管**。
## 一、 约束输入与对齐 (Constraints & Alignment)
基于设计文档,我们需对齐以下硬性约束:
1. **职责边界**
- **模块职责**:严禁在内部无限重试致命错误(如 GPU ECC 错误),必须立即停止并上报。
- **调度器职责**:作为唯一决策者,负责编排恢复流程。
- **Watchdog 职责**:仅在整个进程 Segfault 或调度器死锁时介入。
2. **依赖感知**:恢复不能只重启故障模块,必须先暂停其上游的数据流,防止积压导致 OOM内存溢出
3. **防风暴**:必须集成熔断机制,防止一个持续故障的模块引发系统无限重启循环。
---
## 二、 权衡分析与选项呈现 (Trade-off Matrix)
### 议题 1故障上报内容的标准化 (Fault Reporting Standard)
|**选项**|**A. 仅错误码 (Error Code Only)**|**B. 丰富上下文 (Rich Context) (推荐)**|
|---|---|---|
|**机制**|`ModuleFailedEvent { int code; }`|`ModuleFailedEvent { ErrorCode code; string reason; Snapshot state; TraceID trace; }`|
|**诊断能力**|**低**。日志里只能看到 "Error 1001",无法知道当时 GPU 显存剩多少,或者正在处理哪一帧。|**高**。携带了案发现场的快照和 TraceID能直接关联到导致崩溃的那条控制指令。|
|**传输开销**|极低。|低(拷贝几个字符串和结构体)。|
|**决策支持**|弱。调度器只能无脑重启。|**强**。调度器可根据 `reason` 决定是立即重启,还是降级运行。|
### 议题 2恢复编排策略 (Recovery Orchestration)
|**选项**|**A. 激进重启 (Aggressive Restart)**|**B. 依赖感知流水线 (Dependency-Aware Pipeline) (推荐)**|
|---|---|---|
|**机制**|收到故障立即调用 `module->stop(); module->start();`。|`Pause Upstream` -> `Stop Faulty` -> `Start Faulty` -> `Resume Upstream`。|
|**数据安全性**|**低**。上游模块还在疯狂推数据,故障模块重启期间,中间队列瞬间爆满,导致丢包或内存溢出。|**高**。先截断水源,再修水管,修好再放水。|
|**复杂度**|低。|中。需要 `DependencyGraph` 支持。|
---
## 三、 基线确立与实施规范
为了实现“不仅能活过来,而且不丢数据”的智能恢复,我们确立 **B. 丰富上下文****B. 依赖感知流水线** 为基线。
### 1. 故障事件信封基线 (`ModuleFailedEvent`)
我们定义一个标准化的故障事件结构,作为所有模块的“遗言”。
```cpp
struct ModuleFailedEvent : public BaseEvent {
std::string module_name;
ErrorCode error_code;
bool is_hardware_fault; // 提示调度器:硬件坏了重启也没用,不如报警
std::string debug_info; // 包含显存状态、队列深度等现场快照
// 构造时自动捕获 TraceID
ModuleFailedEvent(string name, ErrorCode code, string info)
: module_name(name), error_code(code), debug_info(info) {
is_hardware_fault = IsHardwareError(code);
}
};
```
### 2. 恢复信令时序基线 (Recovery Signaling Sequence)
这是调度器收到 `ModuleFailedEvent` 后的标准**四步走**恢复协议。以 `SignalProcessor` (信号处理) 崩溃为例,其上游是 `DataReceiver` (数据接收)。
1. **止血 (Pause Upstream)**
- 调度器发布 `PauseDataFlowEvent(target="DataReceiver")`
- `DataReceiver` 响应:停止向中间队列 `push` 数据,暂时丢弃新数据或存入 RingBuffer并回复 `DataFlowPausedEvent`
2. **清理 (Stop Faulty)**
- 调度器发布 `StopModuleEvent(target="SignalProcessor", force=true)`
- `SignalProcessor` 响应:尝试释放 GPU 资源,清理线程。回复 `ModuleStoppedEvent`
3. **重启 (Restart Faulty)**
- 调度器发布 `StartModuleEvent(target="SignalProcessor")`
- `SignalProcessor` 响应:重新初始化 CUDA 上下文,申请内存。回复 `ModuleRunningEvent`
4. **恢复 (Resume Upstream)**
- 调度器发布 `ResumeDataFlowEvent(target="DataReceiver")`
- `DataReceiver` 响应:恢复向中间队列推送数据。系统恢复正常。
### 3. 熔断器集成基线 (Circuit Breaker)
为了防止“垂死挣扎”引发日志爆炸和 CPU 满载,必须在调度器侧实施熔断。
- **策略**:针对每个模块维护一个滑动窗口(如 60 秒)。
- **阈值**:若窗口内收到 **3 次** `ModuleFailedEvent`
- **动作**
- 标记该模块状态为 `BROKEN`
- 不再执行上述恢复流程。
- 发布 `SystemDegradedEvent`(系统降级)或 `SystemFailedEvent`(全系统停机)。
- 记录一条 `FATAL` 日志,呼叫运维人员。
---
## 总结与下一步行动
我们确立了 **2.3.4 故障传播与恢复信令** 的基线:
1. **协议****丰富上下文上报**(带 TraceID 和现场快照)。
2. **编排****依赖感知的四步恢复法**Pause -> Stop -> Restart -> Resume
3. **防护****三振出局**的熔断机制。
下一步建议:
系统能跑能修了,但在资源紧张(比如 GPU 满载)的时候,如何让重要任务(如显控界面渲染)优先运行?这就涉及到 2.3.5 资源仲裁与抢占式优先级控制。这是一个涉及“权力分配”的关键接口。
**提问**:您是否确认 **“依赖感知四步恢复 + 熔断器”** 的故障处理基线?确认后我们将深入 2.3.5。