大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
综合练习
本课串联 nrt-worker、nrt-debug、nrt-cli-tools 与 nrt-apm:CLI 触发 CPU 任务 → Worker 池执行 → 主线程保持响应 → inspect 与 memory 观测。
学习目标
- 实现带 commander 子命令的
hash-batch工具 - 用 Worker 池并行处理多行输入,避免阻塞 Event Loop
- 用
--inspect与memoryUsage验证行为符合预期
项目结构建议
hash-batch/
package.json
bin/hash-batch.js # commander 入口
src/pool.js # Worker 池
src/hash-worker.js # 单任务 worker
test/smoke.test.js # 可选
前置:完成 nodejs-essentials 模块与异步课;可选 nva-cli。
功能需求
-
hash-batch hash <file>- 读文件每行非空字符串
- 提交 Worker 池,算法默认 sha256,
-a可改 - stdout:每行 JSON
{ "line": n, "digest": "..." } - stderr:进度(chalk 可选)
-
Worker 池
- 大小默认
os.availableParallelism(),-j覆盖 - 队列 + 复用 worker,不要「一行 new 一个 Worker」
- worker 异常时 reject 该任务,不拖垮整个进程(参考 nrt-callbacks)
- 大小默认
-
观测
--metricsflag:结束前 stderr 打印memoryUsage与总耗时- 文档说明如何用
node --inspect-brk bin/hash-batch.js hash data.txt断在 pool 调度处
参考片段:池化调度
import { Worker } from "node:worker_threads";
import os from "node:os";
export class WorkerPool {
constructor(size = os.availableParallelism(), workerUrl) {
this.size = size;
this.workerUrl = workerUrl;
this.workers = [];
this.queue = [];
}
run(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this._dispatch();
});
}
_dispatch() {
// 取空闲 worker 或 spawn 至 size 上限;on message resolve
}
}
完整实现留作练习;注意 backpressure:超大文件可逐行 readline 而非一次读入内存(node-streams)。
验收标准
| 项 | 标准 |
|---|---|
| 主线程 | 处理 1 万行时仍可响应简单 heartbeat timer(自测脚本) |
| 正确性 | 与主线程 crypto.createHash 单线程结果一致 |
| CLI | --help、非零 exit code on 文件不存在 |
| 调试 | README 含 inspect 步骤与 heap 对比建议(nrt-gc) |
扩展(可选)
- 子命令
benchmark:对比「无 Worker」与「有 Worker」的 wall time - 对接 nrt-cluster 文档说明:HTTP 服务应 cluster,批处理应 Worker
- 发布为本地 npm link 包(nva-packages)
练习
- 完成
hash-batch hash,对 1000 行 sample 跑通并输出 JSONL - 用
--inspect在 workerpostMessage处下断点,确认任务序列 - 写 README:何时选 Worker vs child_process vs cluster(三句话即可)
小结
CLI 入口清晰、CPU 进 Worker、主线程管 I/O 与观测——这是 runtime 进阶的落地模板。 恭喜完成 nodejs-runtime-essentials;可继续 nestjs-essentials 或深入 observability 专题。