目录
Node.js集群模块:它是做什么的以及如何工作
如何在Node.js应用程序中使用集群模块
如何开发高度可扩展的Express服务器
性能比较
主进程和工作进程之间的通信
零停机时间
使用Node.js集群的主要优势是什么?
Node.js集群是如何工作的?
如何创建一个Node.js集群?
如何处理Node.js集群中的工作进程崩溃?
我可以将Node.js集群与Express.js一起使用吗?
Node.js集群的局限性是什么?
如何在Node.js集群中负载均衡请求?
我可以在生产环境中使用Node.js集群吗?
如何调试Node.js集群?
我可以将Node.js集群与其他Node.js模块一起使用吗?
首页 web前端 js教程 如何创建一个node.js群集以加速您的应用

如何创建一个node.js群集以加速您的应用

Feb 19, 2025 pm 12:01 PM

How to Create a Node.js Cluster for Speeding Up Your Apps

核心要点

  • Node.js凭借其事件驱动架构和非阻塞I/O API,成为处理高流量网站的热门服务器端运行环境,允许异步请求处理。
  • Node.js的可扩展性是其被大型公司采用的关键特性。尽管默认情况下在单线程中运行并具有内存限制,但Node.js可以通过集群模块将单个进程拆分为多个进程或工作进程来扩展应用程序。
  • Node.js集群模块通过多次执行相同的Node.js进程来工作。它允许识别主进程并创建工作进程,这些工作进程可以共享服务器句柄并与父Node进程通信。
  • Node.js应用程序可以使用集群模块进行并行化,允许多个进程同时运行。这提高了系统的效率,改善了应用程序性能,并增强了可靠性和正常运行时间。
  • 虽然Node.js集群模块主要推荐用于Web服务器,但在仔细考虑工作进程之间的任务分配以及工作进程和主进程之间的有效通信的情况下,也可以将其用于其他应用程序。

Node.js作为服务器端运行环境越来越受欢迎,尤其是在高流量网站方面,统计数据也证明了这一点。此外,众多框架的可用性使其成为快速原型设计的良好环境。Node.js具有事件驱动的架构,利用非阻塞I/O API允许异步处理请求。Node.js的一个重要且经常被忽视的特性是其可扩展性。事实上,这是某些大型公司在其平台中集成Node.js(例如Microsoft、Yahoo、Uber和Walmart)甚至将其服务器端操作完全迁移到Node.js(例如PayPal、eBay和Groupon)的主要原因。每个Node.js进程都在单个线程中运行,默认情况下,32位系统的内存限制为512MB,64位系统的内存限制为1GB。尽管可以在32位系统上将内存限制提高到约1GB,在64位系统上提高到约1.7GB,但内存和处理能力仍然可能成为各种进程的瓶颈。Node.js为扩展应用程序提供的优雅解决方案是将单个进程拆分为多个进程或Node.js术语中的工作进程。这可以通过集群模块实现。集群模块允许您创建子进程(工作进程),这些子进程与主Node进程(主进程)共享所有服务器端口。在本文中,您将了解如何创建Node.js集群以加快应用程序的速度。

Node.js集群模块:它是做什么的以及如何工作

集群是在父Node进程下运行的类似工作进程的池。工作进程使用child_processes模块的fork()方法生成。这意味着工作进程可以共享服务器句柄并使用IPC(进程间通信)与父Node进程通信。主进程负责启动和控制工作进程。您可以在主进程中创建任意数量的工作进程。此外,请记住,默认情况下,传入连接在工作进程之间以轮询方式分配(Windows除外)。实际上,还有另一种分配传入连接的方法,这里我不会讨论,它将分配交给操作系统(Windows中的默认设置)。Node.js文档建议使用默认的轮询样式作为调度策略。尽管从理论上讲,使用集群模块听起来很复杂,但其实现非常简单。要开始使用它,您必须将其包含在您的Node.js应用程序中:

1

var cluster = require('cluster');

登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

集群模块多次执行相同的Node.js进程。因此,您需要做的第一件事是确定哪一部分代码用于主进程,哪一部分代码用于工作进程。集群模块允许您如下识别主进程:

1

if(cluster.isMaster) { ... }

登录后复制
登录后复制
登录后复制

主进程是您启动的进程,它又会初始化工作进程。要在主进程中启动工作进程,我们将使用fork()方法:

1

cluster.fork();

登录后复制
登录后复制
登录后复制

此方法返回一个worker对象,其中包含有关已派生的worker的一些方法和属性。我们将在下一节中看到一些示例。集群模块包含多个事件。与工作进程启动和终止时刻相关的两个常见事件是online和exit事件。当工作进程派生并发送online消息时,会发出online事件。当工作进程死亡时,会发出exit事件。稍后,我们将了解如何使用这两个事件来控制工作进程的生命周期。现在,让我们将到目前为止看到的所有内容放在一起,并展示一个完整的可运行示例。

示例

本节包含两个示例。第一个示例是一个简单的应用程序,显示如何在Node.js应用程序中使用集群模块。第二个示例是一个利用Node.js集群模块的Express服务器,它是我通常在大规模项目中使用的生产代码的一部分。这两个示例都可以从GitHub下载。

如何在Node.js应用程序中使用集群模块

在这个第一个示例中,我们设置了一个简单的服务器,它使用包含处理请求的工作进程ID的消息来响应所有传入请求。主进程派生四个工作进程。在每个工作进程中,我们开始监听端口8000以接收传入请求。实现我刚才描述的内容的代码如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

var cluster = require('cluster');

var http = require('http');

var numCPUs = 4;

 

if (cluster.isMaster) {

    for (var i = 0; i < numCPUs; i++) {

        cluster.fork();

    }

} else {

    http.createServer(function(req, res) {

        res.writeHead(200);

        res.end('process ' + process.pid + ' says hello!');

    }).listen(8000);

}

登录后复制
登录后复制

您可以通过启动服务器(运行命令node simple.js)并访问URL https://www.php.cn/link/7d2d180c45c41870f36e747816456190

如何开发高度可扩展的Express服务器

Express是Node.js最流行的Web应用程序框架之一(如果不是最流行的话)。在本网站上,我们已经多次介绍过它。如果您有兴趣了解更多信息,我建议您阅读文章《使用Express 4创建RESTful API》和《构建Node.js驱动的聊天室Web应用程序:Express和Azure》。第二个示例显示了如何开发高度可扩展的Express服务器。它还演示了如何迁移单个进程服务器以利用少量代码的集群模块。

1

var cluster = require('cluster');

登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

此示例的第一个补充是使用Node.js os模块获取CPU内核的数量。os模块包含一个cpus()函数,它返回一个CPU内核数组。使用这种方法,我们可以根据服务器规格动态确定要派生的工作进程数量,以最大限度地利用资源。第二个更重要的补充是处理工作进程的死亡。当工作进程死亡时,集群模块会发出exit事件。可以通过侦听该事件并在发出该事件时执行回调函数来处理它。您可以通过编写类似cluster.on('exit', callback);的语句来做到这一点。在回调函数中,我们派生一个新的工作进程以保持预期的工作进程数量。这允许我们保持应用程序运行,即使有一些未处理的异常。在这个示例中,我还为online事件设置了一个侦听器,每当派生工作进程并准备好接收传入请求时,就会发出该事件。这可用于日志记录或其他操作。

性能比较

有几种工具可以对API进行基准测试,但这里我使用Apache Benchmark工具来分析使用集群模块如何影响应用程序的性能。为了设置测试,我开发了一个Express服务器,它有一个路由和一个用于该路由的回调函数。在回调函数中,执行一个虚拟操作,然后返回一条简短的消息。服务器有两个版本:一个没有工作进程,其中所有操作都在主进程中发生,另一个有8个工作进程(因为我的机器有8个内核)。下表显示了合并集群模块如何增加每秒处理的请求数。

并发连接 1 2 4 8 16
单进程 654 711 783 776 754
8个工作进程 594 1198 2110 3010 3024

(每秒处理的请求数)

高级操作

虽然使用集群模块相对简单,但您可以使用工作进程执行其他操作。例如,您可以使用集群模块实现应用程序的(几乎!)零停机时间。我们过一会儿将了解如何执行其中一些操作。

主进程和工作进程之间的通信

有时,您可能需要从主进程向工作进程发送消息以分配任务或执行其他操作。作为回报,工作进程可能需要通知主进程任务已完成。要侦听消息,应在主进程和工作进程中都设置message事件的事件侦听器:

1

var cluster = require('cluster');

登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

worker对象是fork()方法返回的引用。要在工作进程中侦听来自主进程的消息:

1

if(cluster.isMaster) { ... }

登录后复制
登录后复制
登录后复制

消息可以是字符串或JSON对象。要向特定工作进程发送消息,您可以编写如下所示的代码:

1

cluster.fork();

登录后复制
登录后复制
登录后复制

类似地,要向主进程发送消息,您可以编写:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

var cluster = require('cluster');

var http = require('http');

var numCPUs = 4;

 

if (cluster.isMaster) {

    for (var i = 0; i < numCPUs; i++) {

        cluster.fork();

    }

} else {

    http.createServer(function(req, res) {

        res.writeHead(200);

        res.end('process ' + process.pid + ' says hello!');

    }).listen(8000);

}

登录后复制
登录后复制

在Node.js中,消息是通用的,没有特定类型。因此,最好将消息作为包含有关消息类型、发送者和内容本身的一些信息的JSON对象发送。例如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

var cluster = require('cluster');

 

if(cluster.isMaster) {

    var numWorkers = require('os').cpus().length;

 

    console.log('Master cluster setting up ' + numWorkers + ' workers...');

 

    for(var i = 0; i < numWorkers; i++) {

        cluster.fork();

    }

 

    cluster.on('online', function(worker) {

        console.log('Worker ' + worker.process.pid + ' is online');

    });

 

    cluster.on('exit', function(worker, code, signal) {

        console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);

        console.log('Starting a new worker');

        cluster.fork();

    });

} else {

    var app = require('express')();

    app.all('/*', function(req, res) {res.send('process ' + process.pid + ' says hello!').end();})

 

    var server = app.listen(8000, function() {

        console.log('Process ' + process.pid + ' is listening to all incoming requests');

    });

}

登录后复制

这里需要注意的一点是,message事件回调是异步处理的。没有定义的执行顺序。您可以在GitHub上找到主进程和工作进程之间通信的完整示例。

零停机时间

使用工作进程可以实现的一个重要结果是(几乎)零停机时间服务器。在主进程中,您可以在对应用程序进行更改后,一次一个地终止和重新启动工作进程。这允许您在加载新版本的同时运行旧版本。为了能够在运行时重新启动应用程序,您需要记住两点。首先,主进程一直运行,只有工作进程被终止和重新启动。因此,重要的是要使主进程保持简短,并且只负责管理工作进程。其次,您需要以某种方式通知主进程需要重新启动工作进程。有几种方法可以做到这一点,包括用户输入或监视文件更改。后者效率更高,但您需要在主进程中识别要监视的文件。我建议重新启动工作进程的方法是首先尝试安全地关闭它们;然后,如果它们没有安全终止,则强制杀死它们。您可以通过向工作进程发送关闭消息来执行前者,如下所示:

1

2

3

worker.on('message', function(message) {

    console.log(message);

});

登录后复制

并在工作进程message事件处理程序中启动安全关闭:

1

2

3

process.on('message', function(message) {

    console.log(message);

});

登录后复制

要对所有工作进程执行此操作,您可以使用集群模块的workers属性,该属性保存对所有正在运行的工作进程的引用。我们还可以将所有任务包装在主进程中的一个函数中,该函数可以在我们想要重新启动所有工作进程时调用。

1

var cluster = require('cluster');

登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

我们可以从集群模块中的workers对象获取所有正在运行的工作进程的ID。此对象保存对所有正在运行的工作进程的引用,并在终止和重新启动工作进程时动态更新。首先,我们将所有正在运行的工作进程的ID存储在workerIds数组中。这样,我们避免重新启动新派生的工作进程。然后,我们请求每个工作进程安全关闭。如果5秒后工作进程仍在运行并且仍然存在于workers对象中,那么我们调用工作进程上的kill函数以强制其关闭。您可以在GitHub上找到一个实际示例。

结论

可以使用集群模块对Node.js应用程序进行并行化,以便更有效地使用系统。可以使用几行代码同时运行多个进程,这使得迁移相对容易,因为Node.js处理困难的部分。正如我在性能比较中所展示的那样,通过更有效地利用系统资源,应用程序性能有可能得到显着提高。除了性能之外,您还可以通过在应用程序运行时重新启动工作进程来提高应用程序的可靠性和正常运行时间。也就是说,在考虑在应用程序中使用集群模块时,您需要注意。集群模块的主要推荐用途是用于Web服务器。在其他情况下,您需要仔细研究如何在工作进程之间分配任务,以及如何在工作进程和主进程之间有效地沟通进度。即使对于Web服务器,在对应用程序进行任何更改之前,也要确保单个Node.js进程是瓶颈(内存或CPU),因为您的更改可能会引入错误。最后一点,Node.js网站为集群模块提供了很好的文档。因此,请务必查看一下!

关于Node.js集群的常见问题解答(FAQ)

使用Node.js集群的主要优势是什么?

使用Node.js集群的主要优势是提高应用程序的性能。 Node.js在一个线程上运行,这意味着它一次只能利用一个CPU内核。但是,现代服务器通常有多个内核。通过使用Node.js集群,您可以创建一个主进程,该进程派生多个工作进程,每个工作进程都在不同的CPU内核上运行。这允许您的应用程序同时处理更多请求,从而显着提高其速度和性能。

Node.js集群是如何工作的?

Node.js集群通过创建一个主进程来工作,该主进程派生多个工作进程。主进程侦听传入请求并将它们以轮询方式分发给工作进程。每个工作进程都在单独的CPU内核上运行并独立处理请求。这允许您的应用程序利用所有可用的CPU内核并同时处理更多请求。

如何创建一个Node.js集群?

创建Node.js集群涉及使用Node.js提供的“cluster”模块。首先,您需要导入“cluster”和“os”模块。然后,您可以使用“cluster.fork()”方法来创建工作进程。 “os.cpus().length”为您提供可用的CPU内核数,您可以使用它来确定要创建的工作进程数。这是一个简单的示例:

1

var cluster = require('cluster');

登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

如何处理Node.js集群中的工作进程崩溃?

您可以通过侦听主进程上的“exit”事件来处理Node.js集群中的工作进程崩溃。当工作进程崩溃时,它会向主进程发送“exit”事件。然后,您可以使用“cluster.fork()”方法来创建一个新的工作进程以替换崩溃的工作进程。这是一个示例:

1

if(cluster.isMaster) { ... }

登录后复制
登录后复制
登录后复制

我可以将Node.js集群与Express.js一起使用吗?

是的,您可以将Node.js集群与Express.js一起使用。事实上,使用Node.js集群可以显着提高Express.js应用程序的性能。您只需要将Express.js应用程序代码放在集群脚本中的工作进程代码块中即可。

Node.js集群的局限性是什么?

虽然Node.js集群可以显着提高应用程序的性能,但它也有一些局限性。例如,工作进程不共享状态或内存。这意味着您不能将会话数据存储在内存中,因为它在所有工作进程中都不可访问。相反,您需要使用共享会话存储,例如数据库或Redis服务器。

如何在Node.js集群中负载均衡请求?

默认情况下,Node.js集群中的主进程以轮询方式将传入请求分发给工作进程。这提供了一种基本的负载均衡形式。但是,如果您需要更高级的负载均衡,则可能需要使用反向代理服务器,例如Nginx。

我可以在生产环境中使用Node.js集群吗?

是的,您可以在生产环境中使用Node.js集群。事实上,强烈建议在生产环境中使用Node.js集群,以充分利用服务器的CPU内核并提高应用程序的性能。

如何调试Node.js集群?

调试Node.js集群可能有点棘手,因为您有多个工作进程同时运行。但是,您可以对每个工作进程使用具有唯一端口的“inspect”标志来将调试器附加到每个进程。这是一个示例:

1

cluster.fork();

登录后复制
登录后复制
登录后复制

我可以将Node.js集群与其他Node.js模块一起使用吗?

是的,您可以将Node.js集群与其他Node.js模块一起使用。但是,您需要注意的是,工作进程不共享状态或内存。这意味着如果模块依赖于共享状态,它可能无法在集群环境中正常工作。

以上是如何创建一个node.js群集以加速您的应用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1653
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

前端开发中如何实现类似 VSCode 的面板拖拽调整功能? 前端开发中如何实现类似 VSCode 的面板拖拽调整功能? Apr 04, 2025 pm 02:06 PM

探索前端中类似VSCode的面板拖拽调整功能的实现在前端开发中,如何实现类似于VSCode...

See all articles