123 lines
6.0 KiB
Markdown
123 lines
6.0 KiB
Markdown
---
|
||
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。
|