Ray-D-Song's Blog

Node.js 计算性能瓶颈和发展

2025-4-27 4min

每当提到 Node.js 的计算性能,一定会提到 cluster 和 worker_threads,但这俩并不是什么好的解决方案,只是临时的、打补丁似的思路。
最大的问题就是开销,主要来自于两方面:

首先是通信的损耗,如果用 worker_threads ,主线程和工作线程之间的通信主要通过消息传递。对于大量或复杂数据的传输,数据的序列化、反序列化和复制会带来显著的性能开销。虽然可以使用 SharedArrayBuffer 实现内存共享,但这需要更复杂的同步机制来避免竞态条件。
如果使用 cluster,这个问题更严重,每个工作进程都是一个独立的 Node.js 进程,拥有独立的内存空间。这意味着工作进程之间无法直接共享内存中的数据。如果在应用中需要共享状态(例如用户会话、缓存数据等),需要借助外部存储(如数据库、缓存服务器 Redis 等)或通过 IPC 进行进程间通信来同步数据。
这意味着,即便你构建的是一个巨石架构的单体项目,也需要以大型分布式系统的方式来思考。

第二是 cluster 和 worker_threads 都需要启动独立的 VM 实例,这会带来一定的启动开销和资源消耗。
如果频繁地创建和销毁 Worker,其开销可能会抵消并行带来的好处,为了避免这样的事情发生,最终又需要类似于piscina的池化方案。

那么,有没有办法解决这些问题?
目前有希望的是 Struct 提案。

Struct 提案

proposal-structs(结构体提案) 是 TC39 目前处于 Stage2 的提案,该提案引入了 3 个重要的特性:

这个提案解决了我们的第一个问题,那就是通信间的损耗和并发时的内存安全问题。

如果你对 Struct 提案感兴趣,可以看这里