Skip to content

异步日志系统设计

自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。

背景

XMapEngine 的日志输出在高频场景下(手势拖拽每帧 60 次)严重影响性能。同步写日志每一帧开销 ~2ms——60fps 的帧预算只有 16ms,日志占了 12.5%。

设计

生产者-消费者模型

Producer (主线程)                     Consumer (后台线程)
┌─────────────┐                      ┌─────────────┐
│ 主线程快照    │                      │ 日志拼装     │
│ 提取关键字段  │  ──→ 无锁队列 ──→    │ 格式化字符串  │
│ 投递到队列    │                      │ 写入文件     │
│ < 0.2ms     │                      │ 5-20ms      │
└─────────────┘                      └─────────────┘

核心设计

主线程快照 + 投递

  • 主线程只做字段提取(不需要字符串格式化)
  • 使用 Interlocked 无锁投递到环形 buffer
  • 耗时 < 0.2ms

后台线程拼装

  • 独立线程从队列取数据
  • 做字符串格式化 + 文件 I/O
  • 不阻塞主线程

背压与削峰

  • 环形 buffer 固定大小(1024 条)
  • Buffer 满时:丢弃最旧日志 + 计数器自增(削峰)
  • 降级策略:高频场景关闭详细日志,只记录关键事件

线程安全

  • 环形 buffer:使用 Interlocked.Increment 保证原子性
  • 读写分离:主线程只写 index,后台线程只读 index
  • 无锁设计:避免 mutex 开销

性能

指标同步日志异步日志
主线程开销~2ms/帧< 0.2ms/帧
帧率影响-12.5%< 1%
日志完整性全量削峰时丢少量
崩溃安全性中(环形 buffer 未持久化)

代码结构

cpp
class AsyncLogger {
    RingBuffer<LogEntry> buffer_;  // 环形buffer
    std::thread worker_;            // 后台线程
    std::atomic<uint64_t> dropped_; // 丢弃计数
    
    void Log(LogLevel lvl, const char* fmt, ...);  // 主线程调用
    void WorkerLoop();                              // 后台线程
};

落地

  • XMapEngine 日志后台线程化已落地
  • 支撑线上高频日志场景
  • 问题排查效率提升(日志量增大但性能不降)

公开版深化

案例定位

异步日志系统设计不是孤立笔记,而是稳定性与工程化能力下的一个可复用案例。它服务于“小鹏一张图 / SR 渲染引擎”这条主线,公开版重点保留问题抽象、工程取舍和可复用方法,不暴露内部系统细节。

关键问题

自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。

这篇文章已经覆盖 背景、设计、性能、代码结构、落地。后续阅读时应重点看三件事:问题如何被定义,方案如何在约束下落地,以及哪些经验可以迁移到下一次类似项目。

企业级产出

产出公开表达
问题定义用用户体验、性能、稳定性或交付效率描述影响
技术方案保留架构、流程、算法和工具链层面的抽象
指标证据只使用页面已有数字或经过脱敏审查的量级
复用方法沉淀为 SOP、检查清单、图谱关系或后续案例链接

指标与证据

  • 自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。
  • XMapEngine 的日志输出在高频场景下(手势拖拽每帧 60 次)严重影响性能。同步写日志每一帧开销 ~2ms——60fps 的帧预算只有 16ms,日志占了 12.5%。
  • │ < 0.2ms │ │ 5-20ms │
  • 耗时 < 0.2ms

复盘结论

这个案例的核心价值,是把一次具体工程处理沉淀成可检索、可复盘、可继续扩展的技术资产。没有公开证据支撑的细节继续留在私有材料池,不进入线上页面。

公开版深化

案例定位

异步日志系统设计不是孤立笔记,而是稳定性与工程化能力下的一个可复用案例。它服务于“小鹏一张图 / SR 渲染引擎”这条主线,公开版重点保留问题抽象、工程取舍和可复用方法,不暴露内部系统细节。

关键问题

自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。

这篇文章已经覆盖 背景、设计、性能、代码结构、落地。后续阅读时应重点看三件事:问题如何被定义,方案如何在约束下落地,以及哪些经验可以迁移到下一次类似项目。

企业级产出

产出公开表达
问题定义用用户体验、性能、稳定性或交付效率描述影响
技术方案保留架构、流程、算法和工具链层面的抽象
指标证据只使用页面已有数字或经过脱敏审查的量级
复用方法沉淀为 SOP、检查清单、图谱关系或后续案例链接

指标与证据

  • 自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。
  • XMapEngine 的日志输出在高频场景下(手势拖拽每帧 60 次)严重影响性能。同步写日志每一帧开销 ~2ms——60fps 的帧预算只有 16ms,日志占了 12.5%。
  • │ < 0.2ms │ │ 5-20ms │
  • 耗时 < 0.2ms

复盘结论

这个案例的核心价值,是把一次具体工程处理沉淀成可检索、可复盘、可继续扩展的技术资产。没有公开证据支撑的细节继续留在私有材料池,不进入线上页面。

公开版深化

案例定位

异步日志系统设计不是孤立笔记,而是稳定性与工程化能力下的一个可复用案例。它服务于“小鹏一张图 / SR 渲染引擎”这条主线,公开版重点保留问题抽象、工程取舍和可复用方法,不暴露内部系统细节。

关键问题

自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。

这篇文章已经覆盖 背景、设计、性能、代码结构、落地。后续阅读时应重点看三件事:问题如何被定义,方案如何在约束下落地,以及哪些经验可以迁移到下一次类似项目。

企业级产出

产出公开表达
问题定义用用户体验、性能、稳定性或交付效率描述影响
技术方案保留架构、流程、算法和工具链层面的抽象
指标证据只使用页面已有数字或经过脱敏审查的量级
复用方法沉淀为 SOP、检查清单、图谱关系或后续案例链接

指标与证据

  • 自研生产者-消费者异步日志系统,主线程投递 < 0.2ms,后台线程拼装 5-20ms,背压 + 削峰 + 线程安全。
  • XMapEngine 的日志输出在高频场景下(手势拖拽每帧 60 次)严重影响性能。同步写日志每一帧开销 ~2ms——60fps 的帧预算只有 16ms,日志占了 12.5%。
  • │ < 0.2ms │ │ 5-20ms │
  • 耗时 < 0.2ms

复盘结论

这个案例的核心价值,是把一次具体工程处理沉淀成可检索、可复盘、可继续扩展的技术资产。没有公开证据支撑的细节继续留在私有材料池,不进入线上页面。

企业级技术案例库 · 内容先审计再发布