跳转至

ADR 007: 弱网容错分析

状态

已接受 (2026-02-12)

背景

在 v3.0.4 版本中,对项目的弱网支持能力进行了全面分析,发现以下关键问题:

  1. 网络组件不统一:项目存在四套独立的网络请求实现(FetchWorkerNetworkUtilsNetworkWorkerComponentService),各自的超时/重试/退避策略不一致
  2. NetworkWorker 无超时机制:使用 QEventLoop::exec() 无限等待,弱网下可能永久阻塞线程
  3. FetchWorker 超时不重试:超时是弱网最常见的错误类型,但 FetchWorker 在超时后直接放弃重试
  4. 超时时间配置不合理FetchWorker 的超时时间(8-10s)对弱网环境过短

分析结论

问题严重性分级

严重程度 问题 影响
严重 NetworkWorker 无超时,永久阻塞 程序无响应
严重 FetchWorker 超时不重试 弱网下批量导出全部失败
严重 超时时间过短(8-10s) RTT > 2s 时首次连接大概率超时
中等 惊群效应 带宽竞争加剧
中等 线性退避(非指数退避) 限流恢复慢
中等 固定 500ms 重试延迟 弱网下过于激进
QNAM thread_local 泄漏 长期运行内存增长

各组件弱网能力对比

组件 超时 重试 退避策略 弱网评级
FetchWorker 8-10s 3次(超时不重试) 线性 +1000ms
NetworkUtils 30s 3次(超时可重试) 递增 3/5/10s 良好
NetworkWorker 极差
ComponentService 15s 3次 递增 1/2/3s 中等

决策

改进方向

基于分析结论,建议分两个优先级实施改进:

P0 改进(优先实施)

  1. 统一网络超时机制
  2. NetworkWorker 添加超时保护
  3. 评估是否将 NetworkWorker 迁移至 FetchWorkerNetworkUtils

  4. 修复 FetchWorker 超时重试逻辑

  5. OperationCanceledError(超时)执行正常重试
  6. NetworkUtils 的超时重试行为保持一致

  7. 调整超时时间

  8. 组件信息:8s -> 15-20s
  9. 3D 模型:10s -> 30s
  10. NetworkUtils 的超时配置保持一致

P1 改进(后续实施)

  1. 统一退避策略
  2. 实现真正的指数退避(1s -> 2s -> 4s -> 8s)
  3. 加入随机抖动(Jitter)避免惊群效应

  4. 统一重试延迟

  5. 采用 NetworkUtils 的递增延迟模式(3s -> 5s -> 10s)

  6. 修复 QNAM 内存管理

  7. 使用 std::unique_ptr 管理 thread_local 对象

后果

正面

  • 明确了项目弱网支持的现状和改进方向
  • 为后续版本的网络容错改进提供了清晰的优先级指导
  • 统一各组件的网络策略标准

负面

  • 改进工作需要投入额外的开发和测试时间
  • 增加超时时间可能导致正常网络下的等待时间略有增加(可通过动态超时策略缓解)

风险

  • NetworkWorker 的改动需要确认其是否仍被活跃使用,避免不必要的修改
  • 超时时间调整需要在弱网容错和用户体验之间取得平衡

参考文档