标准答案
- V8 负责解析、执行和优化 JavaScript,并管理 JavaScript 堆。
- 事件循环调度已经完成的 I/O、定时器和回调;libuv 处理跨平台异步能力和部分线程池任务。
- Node API 可能把工作交给内核、线程池或其他系统资源,不能把所有异步都理解成单线程执行。
- 单个 JavaScript 主线程仍应避免长时间计算,否则会阻塞同一进程中的其他请求。
题目解析
“Node 单线程”主要指一个进程中的 JavaScript 回调通常在主线程串行执行;libuv、操作系统、DNS、文件、加密和 Worker 仍可能使用其他线程或内核资源。
异步 API 的等待可以不占住主线程,但回调本身、序列化、解析和业务计算仍然消耗 CPU。主线程被长任务占住时,其他连接的回调同样无法及时运行。
排查内存要区分 V8 heapUsed、external/Buffer、线程栈、native 内存和进程 RSS。运行时组成决定了服务的容量边界,不能只用“单线程”解释所有问题。
常见误区
- 误区:认为 Node 没有后台线程。改正:区分 JavaScript 主线程、libuv 线程池、Worker 和操作系统异步 I/O。
- 误区:认为所有异步 API 都不会占 CPU。改正:回调、解析、序列化和计算仍在某个执行单元消耗 CPU。
- 误区:把 V8 堆和进程 RSS 当成同一个指标。改正:同时观察 heap、external、Buffer、线程和 native 资源。