Node.js 默认单线程运行,难以充分利用现代多核服务器资源。本文介绍通过 child_process 模块的 fork、spawn 等方法,采用 Master-Worker 主从模式实现多核利用。重点解析四种创建子进程的方式及其差异,强调 fork 的高开销特性,并澄清多进程旨在提升 CPU 利用率而非解决并发瓶颈。
概述
Node.js 基于 Chrome 浏览器的 V8 引擎构建,其运行模型与浏览器相似。JavaScript 代码在单个进程的单个线程中执行。
然而,V8 引擎的单进程单线程模型并非完美适配现代硬件。当前服务器通常配备多个 CPU 核心(例如线上物理机可能拥有 12 个核心)。这引出了 Node.js 在实际应用中的一个关键问题:如何充分利用多核 CPU 服务器?
严格来说,Node.js 并非真正的单线程架构,因为它包含处理网络 I/O 和磁盘 I/O 的底层 libuv 线程。这些 I/O 线程对 JavaScript 开发者透明,JavaScript 代码始终在 V8 引擎的单线程中运行,因此表面上看 Node.js 是单线程的。
Node.js 充分利用多核 CPU 的方法
针对单进程单线程对多核利用率低的问题,常规思路是让每个进程占用一个 CPU 核心,从而实现多核利用。Node.js 提供了 child_process 模块,并通过 fork() 方法实现进程复制。需要注意的是,进程复制需要消耗资源,Node.js 复制进程至少需要 10M 内存和 30ms 时间。
这种解决方案对应于 *nix 系统上经典的主从模式(Master-Worker 模式)。
这种典型的并行处理业务模式具备分布式架构的可伸缩性和稳定性。可伸缩性涉及算法与并行计算机体系结构的匹配,反映算法能否有效利用不断增加的 CPU 资源。
在该模式中,主进程不负责具体业务处理,而是负责调度和管理工作进程;工作进程则负责具体的业务逻辑。因此,工作进程的稳定性是开发人员需要重点关注的方面。

通过 fork() 复制的进程是独立的,拥有独立且全新的 V8 实例。尽管 Node.js 提供 fork() 来利用每个 CPU 内核,但必须记住 fork 进程的代价很大。好在 Node.js 通过事件驱动机制,能在单个线程上处理高并发请求。
注意:这里启动多个进程的主要目的是充分利用 CPU 资源,而非解决并发问题。
Node 创建子进程的 4 种方式
1、spawn()
用于创建一个子进程来执行命令。
2、exec()
用于创建一个子进程来执行命令。与 spawn() 不同,exec() 的参数不同,它允许传入回调函数以获取子进程的状态。
3、execFile()
用于启动一个子进程来执行指定文件。需注意,该文件顶部必须声明 SHEBANG 符号 (#!) 以指定进程类型。
4、fork()
与 spawn() 类似,不同之处在于它创建 Node.js 子进程时,只需指定要执行的 JavaScript 文件模块即可。
注意:上述后三种方法均为 spawn() 的延伸应用。
以上即为 Node.js 充分利用多核 CPU 的详细内容,更多关于 Node.js 充分利用多核 CPU 的资料请关注本站其它相关文章!