NodeJS 集群模块: 为App创建集群实例
目录
推荐超级课程:
本文介绍了在 Node.js 中进行集群处理以及如何使您的应用程序受益于扩展。您将使用集群模块 以创建集群实例。您将学到:
- 为什么需要集群作为扩展 Node.js 应用程序的策略。
- 如何使用原生和 PM2 模块使用 express 创建和扩展 Node.js 集群。
- 集群和非集群 Node.js 应用程序之间的扩展比较。
- 对 Node.js 集群进行负载测试作为性能监控方法。
- 如果 Node.js 集群不符合您的应用设计,需要了解的事项。
Node.js 集群介绍:终极扩展策略
Node.js 默认情况下是单线程的运行时。这意味着运行中的 Node.js 仅利用计算机的一个核心(CPU 单元),即使任何一台计算机都有多个处理器。例如,如果您在一台有 4 个处理器的计算机上运行 Node.js 应用程序,则只使用其中一个。然而,Node.js 允许您使用集群,充分利用多核处理器,并将您的 Node.js 应用程序扩展到新的水平。
使用集群模块开始扩展 Node.js
以拥有四个处理器的计算机为例。Node.js 只会利用其处理能力的 25%。Node.js 运行一个 worker Node 来执行所有你的 Node.js 函数。这种策略在您的应用程序中运行了密集任务时会受到影响。worker Node 将在重任务进行中被阻塞。
Node.js 集群的概念是创建多个您的 Node.js 应用程序实例(worker)。这将为同一应用程序创建一个跨可用 CPU 核心分布负载的集群。在这种情况下,当您的重任务正在处理时,您的集群模块将将任何连续的任务生成到剩余的处理器中。简而言之,集群将增强应用程序的性能和可扩展性。
让我们深入学习如何添加 Node.js worker 集群并利用计算机的全部处理能力。
扩展 Node.js 的两种集群策略
如果您希望在 Node.js 中使用集群,有两种方式可以实现这一点:
- 使用原生 Cluster模块。
- 使用进程管理器,例如PM2。
- 原生 Cluster
Node.js 自带一个内置的集群模块。它允许您手动将 worker 分叉到可用处理器上。这样,Node.js 将跨多个子进程分配传入请求以增强可伸缩性。
- 使用 PM2 进行集群处理
PM2 是一个生产级流程管理器。像原生集群模块一样,PM2 具有内置的集群支持。但是,它固有地还伴随其他与生产相关的元素,例如:
- 零停机部署。
- 应用程序监控。
- 日志和指标管理。
- 自动应用程序重启。
使用集群受益的 Node.js 应用程序示例
现在您了解了 Node.js 集群以及您可以使用的方法,让我们演示如何集群对于可伸缩性是如何有利的。您将创建两个简单示例,一个不使用集群,另一个使用集群,并使用想象的用户来模拟和扩展测试以比较性能。
没有集群的 Node.js:不可伸缩的原则
由于 Node.js 是单线程的,它必须在处理应用程序内的其他任务之前完成一个任务的执行。这个概念关乎 Node.js 单线程方面,它只使用一台计算机处理器。
要演示这个工作原理,您可以使用Express创建一个简单的 Node.js 应用程序,如下所示:
const express = require("express");
const PORT = 3000;
const app = express();
// 模拟一个耗时任务
app.get("/compute", (req, res) => {
const startTime = Date.now();
// 模拟一个 10 秒的计算
const duration = 10000;
while (Date.now() - startTime < duration) {
}
res.send("计算完成!");
});
// 提供一个简单的 HTTP 请求
app.get("/hello", (req, res) => {
res.send("来自 worker 进程的问候!");
});
app.listen(PORT, () => {
console.log(`应用程序正在端口 ${
PORT} 上监听`);
});
上面的示例创建了两个 GET 请求:
- 一个简单的 GET 请求,发送一个基本请求
- 一个模拟的 GET 请求,执行 10 秒来返回用户请求
假设的模拟 10 秒任务现在代表任何您可以执行的耗时任务。根据 Node.js 的工作方式,如果发送一个请求来执行 localhost:3000/compute
,Node.js 将锁定到单个处理器上,并且无法执行其他任务。
这个任务需要 10 秒,并锁定您的计算资源,直到其计算完成:
这意味着如果您在 localhost:3000/compute
正在运行时执行 localhost:3000/hello
,localhost:3000/hello
将无法返回其响应,即使它只是一个简单的 GET 请求:
考虑到这种简单的方法,一个生产环境的 Node.js 应用程序一定会有许多耗时的函数。您不希望这样的场景锁定其他任务的执行。为了解决这个问题,Node.js 可以创建相同应用程序的分支,将它们复制到每一个可用的处理器,并创建一个并发执行的集群。
集群操作:一个扩展的 Node.js 应用程序
使用上面的非集群示例,这是如何将 Node.js 集群引入相同应用程序的方法:
const express = require