附录 G: 网络故障矩阵
定义各种网络故障场景的检测和处理策略
故障类型分类
一级分类
| 类型 | 说明 | 用户影响 |
|---|---|---|
| 完全离线 | 无任何网络连接 | 高 |
| 部分可达 | 部分服务可用 | 中 |
| 高延迟 | 响应缓慢 | 中 |
| 不稳定 | 间歇性断连 | 低-中 |
| 服务端故障 | 服务器不可用 | 高 |
故障检测
检测方法
| 方法 | 用途 | 频率 |
|---|---|---|
| navigator.onLine | 基础离线检测 | 实时事件 |
| 心跳请求 | 服务可用性 | 30s |
| 请求超时监控 | 延迟检测 | 每次请求 |
| 错误率统计 | 稳定性评估 | 滑动窗口 |
检测指标
NetworkHealth {
isOnline: boolean // 基础连接状态
latency: number // 平均延迟 (ms)
errorRate: number // 错误率 (%)
lastSuccessTime: number // 上次成功时间
connectionType: string // 连接类型 (wifi/4g/3g)
}健康度评级
| 评级 | 条件 | 状态 |
|---|---|---|
| healthy | errorRate < 5% && latency < 1s | 正常 |
| degraded | errorRate < 20% && latency < 3s | 降级 |
| poor | errorRate < 50% && latency < 10s | 较差 |
| offline | errorRate >= 50% |
故障场景矩阵
场景 1: 完全离线
检测: navigator.onLine === false
| 功能 | 处理方式 | UI 反馈 |
|---|---|---|
| 查看钱包 | 使用缓存 | 显示缓存时间 |
| 查看余额 | 使用缓存 | "离线模式" 标签 |
| 发起转账 | 离线签名 | "待发送" 状态 |
| 扫码 | 正常可用 | 无 |
| 设置 | 正常可用 | 无 |
恢复动作:
- 检测到网络恢复
- 刷新关键数据
- 处理待发送队列
- 移除离线提示
场景 2: 服务端不可用 (5xx)
检测: API 返回 500/502/503
| 功能 | 处理方式 | UI 反馈 |
|---|---|---|
| 余额查询 | 重试 → 缓存 | 显示缓存 + 警告 |
| 交易历史 | 重试 → 缓存 | 显示缓存 |
| 广播交易 | 重试 3 次 | 显示进度 |
| 链配置 | 使用本地 | 无 |
重试策略:
第 1 次重试: 1s 后
第 2 次重试: 2s 后
第 3 次重试: 4s 后
放弃并使用缓存/提示错误场景 3: 节点不可用
检测: RPC 请求超时或返回错误
| 功能 | 处理方式 | UI 反馈 |
|---|---|---|
| 余额查询 | 切换节点 | 短暂加载 |
| 广播交易 | 切换节点 | 短暂延迟 |
| Gas 估算 | 切换节点 | 短暂延迟 |
节点切换逻辑:
主节点请求
│
├── 成功 ──► 返回结果
│
└── 失败
│
▼
尝试备用节点 1
│
├── 成功 ──► 返回结果 + 标记主节点不健康
│
└── 失败 ──► 尝试备用节点 2 ──► ... ──► 全部失败
│
▼
返回错误场景 4: 高延迟 (>3s)
检测: 请求响应时间 > 3s
| 功能 | 处理方式 | UI 反馈 |
|---|---|---|
| 页面加载 | 显示骨架屏 | 加载指示器 |
| 余额刷新 | 显示旧数据 | "加载中" 覆盖 |
| 交易广播 | 等待 | 进度指示 |
优化措施:
- 并行请求改为串行
- 降低轮询频率
- 优先使用缓存
场景 5: 网络不稳定 (频繁断连)
检测: 5 分钟内断连 > 3 次
| 功能 | 处理方式 | UI 反馈 |
|---|---|---|
| 数据同步 | 增加重试 | "网络不稳定" |
| 实时更新 | 降级轮询 | 更新频率降低 |
| 交易广播 | 持久化重试 | 队列状态显示 |
场景 6: 特定 API 故障
检测: 单个 API 持续失败,其他正常
| 故障 API | 处理方式 | UI 反馈 |
|---|---|---|
| 余额 API | 缓存 + 标记 | 显示缓存时间 |
| 历史 API | 缓存 | 显示缓存数据 |
| 汇率 API | 缓存 | 隐藏法币金额 |
| 链配置 | 本地配置 | 无 |
恢复策略
自动恢复
| 场景 | 检测间隔 | 恢复动作 |
|---|---|---|
| 网络恢复 | 实时 | 刷新数据 + 处理队列 |
| 服务恢复 | 30s | 重试失败请求 |
| 节点恢复 | 5min | 切回主节点 |
恢复后动作优先级
1. [高] 广播待发送交易
2. [高] 刷新当前钱包余额
3. [中] 同步交易历史
4. [中] 更新其他钱包余额
5. [低] 更新链配置
6. [低] 预加载数据恢复验证
| 验证项 | 方法 |
|---|---|
| 网络真正恢复 | 发送测试请求 |
| 数据一致性 | 对比缓存和最新 |
| 队列处理完成 | 检查待发送队列 |
用户通知
通知级别
| 级别 | 场景 | 展示方式 |
|---|---|---|
| 全局横幅 | 完全离线 | 固定顶部 |
| Toast | 临时故障 | 自动消失 |
| 内联提示 | 特定功能不可用 | 功能旁边 |
| 无提示 | 自动恢复的短暂故障 | 静默处理 |
通知内容
| 场景 | 消息 |
|---|---|
| 离线 | "当前离线,显示的是缓存数据" |
| 服务故障 | "服务暂时不可用,正在重试" |
| 高延迟 | "网络较慢,请耐心等待" |
| 恢复 | "网络已恢复" |
监控指标
需要监控的指标
| 指标 | 说明 | 告警阈值 |
|---|---|---|
| 离线用户占比 | 当前离线用户数/总用户 | > 10% |
| API 错误率 | 失败请求/总请求 | > 5% |
| P95 延迟 | 95% 请求的延迟 | > 3s |
| 节点切换率 | 切换次数/请求数 | > 20% |
故障报告
NetworkFaultReport {
faultType: FaultType
startTime: number
endTime?: number
affectedFeatures: string[]
userActions: string[]
recoveryMethod: string
}测试场景
必须测试的场景
| 场景 | 测试方法 | 验证点 |
|---|---|---|
| 启动时离线 | 断网后启动 | 显示缓存 |
| 使用中断网 | 拔网线/开飞行 | 及时提示 |
| 慢速网络 | 节流 3G | 不卡死 |
| 节点故障 | Mock 返回错误 | 自动切换 |
| 恢复后同步 | 断网→操作→恢复 | 数据同步 |
自动化测试
测试结构:
describe('Network Faults', () => {
describe('Offline Mode', () => {
it('shows cached balance when offline')
it('queues transactions for later')
it('syncs when back online')
})
describe('Node Failover', () => {
it('switches to backup node')
it('returns to primary when healthy')
})
})本章小结
- 完整覆盖各种网络故障场景
- 每种故障都有明确的检测和处理方式
- 自动恢复优先,必要时通知用户
- 完善的监控和告警机制
- 测试场景覆盖所有故障类型