Skip to content

Latest commit

 

History

History
198 lines (151 loc) · 9.8 KB

File metadata and controls

198 lines (151 loc) · 9.8 KB

GOAL

核心目标

帮助用户快速排查 Node.js 进程的异常根因。

当线上 JS 进程出现 CPU 飙高、内存泄漏、未捕获异常或定时器异常时,用户能够在最短时间内定位到问题的根本原因并采取行动。


CLI 使用模式

mito-node CLI 提供两种等价的使用方式,覆盖「人」和「AI Agent」两类用户:

1. 交互式 TUI 模式(供人使用)

面向开发者和运维人员的终端交互界面,基于 Ink/React 构建。

使用场景:

  • 开发者收到告警,需要实时观察进程状态
  • 排查生产环境偶发性问题,需要持续监控
  • 需要人工判断和操作的复杂调试流程

交互流程:

  1. 自动发现当前系统中的 Node.js 进程
  2. 选择目标进程
  3. 选择诊断命令
  4. 实时展示诊断结果(图表、表格、日志)

设计原则:

  • 零配置启动,开箱即用
  • 可视化呈现关键指标(CPU 使用率曲线、内存分布图)
  • 引导式操作,降低排障门槛

2. 快捷参数模式(供 AI Agent 使用)

面向 AI Agent 的非交互式调用接口,通过命令行参数一次性指定目标和操作。

使用场景:

  • AI Agent 自动诊断异常进程
  • CI/CD 流水线中的自动化健康检查
  • 脚本编排多步骤诊断流程

调用方式:

# 采集 CPU Profile
mito-node cpuprofile -p <pid> -d 10000

# 获取内存信息
mito-node memory -p <pid>

# 生成进程诊断报告
mito-node report -p <pid>

# 获取堆快照
mito-node heapsnapshot -p <pid>

# 远程执行代码
mito-node run-code -p <pid> -c "process.memoryUsage()"

设计原则:

  • 结构化输出(JSON),方便 Agent 解析
  • 单次调用完成单一诊断动作,无副作用
  • 明确的退出码,便于流程控制
  • 快速响应,超时可控

解决的痛点

痛点 解决方案
Node.js 进程异常时不知道从哪里入手 提供引导式排障流程和一键诊断命令
CPU Profiling / Heap Snapshot 操作复杂 一条命令完成采集,自动保存文件
线上环境无法安装调试工具 通过 Inspector 协议远程连接,无需重启进程
AI Agent 无法理解进程状态 提供结构化数据输出,Agent 可直接推理
定时器泄漏难以定位 Shimmer 劫持 setTimeout/setInterval,记录创建调用栈
传统 APM 开销大、侵入性强 轻量 SDK + Rust Agent 高性能数据处理,最小化对业务的影响

诊断能力矩阵

异常类型 诊断手段 输出产物
CPU 飙高 CPU Profiling .cpuprofile 文件(可导入 Chrome DevTools)
内存泄漏 Heap Snapshot + 内存趋势监控 .heapsnapshot 文件 + 内存使用数据
未捕获异常 JS Error 采集 错误堆栈 + 上下文信息
定时器异常 setTimeout/setInterval 劫持 定时器创建记录 + 调用栈
进程状态异常 Process Report Node.js 诊断报告(libuv handles、环境变量等)
任意运行时状态 远程代码执行 表达式求值结果

系统架构与分工

┌─────────────────────────────────────────────────────────┐
│                    用户 / AI Agent                        │
├─────────────────────────────────────────────────────────┤
│         mito-node CLI(Inspector 协议连接)               │
│    ┌──────────────────┬──────────────────────┐          │
│    │  TUI 模式 (Ink)  │  参数模式 (Commander) │          │
│    └──────────────────┴──────────────────────┘          │
├─────────────────────────────────────────────────────────┤
│              目标 Node.js 进程                            │
│    ┌──────────────────────────────────────────┐         │
│    │  @mitojs/node SDK(嵌入式采集)           │         │
│    │  Collectors → Subjects → Rust Agent      │         │
│    └──────────────────────────────────────────┘         │
└─────────────────────────────────────────────────────────┘
  • CLI 负责「连接 → 诊断 → 呈现」,是用户/Agent 的操作入口
  • SDK 负责「采集 → 传输」,嵌入目标进程持续收集运行时数据
  • Rust Agent 负责「接收 → 处理 → 存储」,高性能后端,不影响 JS 主线程

代码工程规范

分层架构

代码必须按职责清晰分层,禁止跨层直接调用:

┌─────────────────────────────────────────┐
│  Interface Layer(接口层)               │
│  CLI 命令解析 / TUI 渲染 / JSON 输出    │
├─────────────────────────────────────────┤
│  Service Layer(服务层)                 │
│  诊断流程编排 / Inspector 会话管理       │
├─────────────────────────────────────────┤
│  Core Layer(核心层)                    │
│  Collector / Subject / 数据模型          │
├─────────────────────────────────────────┤
│  Infrastructure Layer(基础设施层)       │
│  IPC 通信 / Binary 管理 / Worker Thread │
└─────────────────────────────────────────┘

原则:

  • 上层依赖下层,下层不感知上层
  • 每层通过明确的接口(interface/type)暴露能力
  • 跨层数据传递使用定义好的 DTO,不透传内部结构

插件系统

诊断能力通过插件机制扩展,而非硬编码:

interface DiagnosticPlugin {
  name: string
  description: string
  // 该插件支持的诊断场景
  supports: DiagnosticScenario[]
  // 执行诊断,返回结构化结果
  execute(context: DiagnosticContext): Promise<DiagnosticResult>
  // 可选:提供 TUI 渲染组件
  render?: (data: DiagnosticResult) => ReactElement
}

设计目标:

  • 新增诊断能力只需实现一个 Plugin,无需修改核心流程
  • 内置插件:CPU Profiling、Heap Snapshot、Memory Info、Process Report、JS Error、Timeout Detection
  • 插件可声明依赖关系(如「内存泄漏诊断」依赖「Heap Snapshot」+「Memory Trend」)
  • CLI 命令自动从已注册插件生成,保持命令与能力的一致性

注释规范

代码默认不写注释,但以下关键位置必须添加注释:

场景 说明 示例
非显而易见的设计决策 解释 WHY,不解释 WHAT // 使用 fd 3 而非 stdio 避免与子进程日志混淆
平台兼容性处理 标注哪些平台需要特殊逻辑 // Windows 不支持 SIGUSR1,改用 named pipe 激活 Inspector
性能关键路径 标注为什么选择某种实现方式 // 使用 BigInt hrtime 避免浮点精度丢失导致 CPU 计算偏差
协议/规范约束 引用外部规范 // Chrome DevTools Protocol: Runtime.evaluate
临时 workaround 标注上下文和移除条件 // WORKAROUND: Node 18 Inspector 在 worker 中不触发 ready 事件,v20 已修复
插件接口契约 说明实现者必须遵守的约束 // 插件必须在 30s 内返回结果,超时将被强制终止

禁止的注释:

  • 重复代码语义的注释(// 获取内存信息getMemoryInfo()
  • 变更日志式注释(// 2024-01-01: 新增 xxx
  • 注释掉的代码块(直接删除,用 git 追溯)

成功标准

  1. 用户从发现异常到定位根因的时间 < 5 分钟
  2. AI Agent 能通过 CLI 输出独立完成 80% 的常见异常诊断
  3. SDK 对目标进程的性能影响 < 1% CPU / < 10MB 内存
  4. 支持不重启进程的情况下完成全部诊断操作
  5. 新增诊断能力只需实现一个插件,不修改核心代码
  6. 任何开发者阅读代码时,能通过分层和命名快速理解模块职责