Node.js 中使用 worker_threads 处理 CPU 密集型任务时,为什么你的性能反而下降了?
上个月帮朋友排查一个图片处理服务的性能问题,他们用 Node.js 起了一个 HTTP 服务,收到请求后对上传的图片做缩放和格式转换,用的是 sharp。逻辑本身没问题,但压测时 QPS 死活上不去,CPU 占用却跑满了。他听说 worker_threads 可以把计算任务挪到子线程,避免阻塞事件循环,于是把 sharp 调用包进了 Worker 里,结果吞吐量几乎没变,内存倒是涨了不少,偶尔还会触发 OOM。这个场景很典型:Node.js 主线程被 CPU 密集任务卡住,直觉上应该交给 worker 线程,但实际效果取决于任务本身的特性、数据的传输成本以及线程池的调度方式。这篇文章从 V8 的线程模型和 worker_threads 的通信机制出发,结合实际代码说明什么情况下 worker 能带来收益,什么情况下反而会拖慢服务,以及如何用正确的方式做任务分流。