在上一篇文章“Node JS 内部结构”中,我们讨论了 Node JS 内部架构,并讨论了为什么我们应该增加节点线程池大小以同时处理多个请求。我已经告诉过你,可扩展性和性能与线程池大小无关。
为了可扩展性和高性能,我们可以使用集群和工作线程。
聚类
假设您正在参加一场盛大的婚礼,有数千名宾客参加婚礼。有一间厨房,一名厨师正在为所有这些客人准备食物。听起来不可预测,对吧?如果您只有一名厨师,您就没有充分利用厨房的全部资源。
这正是在多核 CPU 上运行的 Node JS 应用程序中发生的情况,当仅使用一个核心来处理所有请求时。因此,即使我们的机器具有多核的能力,如果没有集群,我们的应用程序也只能在单核上运行。一个核心负责处理所有工作。
当你的厨房里有多个厨师正在工作时,这就是集群。
集群是一种使单个 Node JS 应用程序能够有效利用多个 CPU 核心的技术。
要实现集群,您必须使用 Node JS 中的集群模块。
const cluster = require('cluster');
通过使用此集群模块,您可以创建 Node JS 应用程序的多个实例。这些实例称为工人。所有工作人员共享相同的服务器端口并同时处理传入请求。
集群架构中有两种类型的进程。
1.主流程:
Master进程就像厨房里的主厨管理工人。它初始化应用程序,设置集群环境,并将任务委托给工作进程。它不直接处理应用程序请求。
Master进程是做什么的?
使用 cluster.fork() 方法创建多个工作进程。如果工作人员意外崩溃或退出,它还会重新启动工作人员。
它确保传入请求分布在所有工作进程中。在 Linux 上,这是由操作系统处理的,在 Windows 上,Node JS 本身充当负载均衡器。
它可以通过IPC(进程间通信)在worker之间进行通信。
2.工作进程:
工作进程是主进程创建的 Node JS 应用程序的实例。每个进程在单独的 CPU 核心上独立运行并处理传入请求。
工作进程无法直接相互通信,它们通过主进程进行通信。
工作进程处理传入的请求并执行一些任务,例如数据库查询、计算或任何应用程序逻辑。
const cluster = require('cluster');
在这里,我们首先检查这是主进程。如果是,那么它将创建工作进程。
在我们的代码中,我使用 cluster.fork() 创建一个工作进程。
但是,这不是创建工作进程的理想方式。
假设您正在创建 4 个工作进程,并且您的系统有两个核心。
为了解决这个问题,而不是创建硬编码的工作进程,首先找到 CPU 核心,然后考虑数据创建工作进程。
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers cluster.fork(); cluster.fork(); cluster.fork(); cluster.fork(); } else { console.log(`Worker ${process.pid} is running`); // Worker logic (e.g., server setup) goes here }
我使用双核系统,所以输出将如下所示。
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); const numCPUs = os.cpus().length; // Fork workers for (let i = 0; i <p><strong>现在,您有一个问题,如果您有双核 CPU,那么为什么要创建 4 个工作进程?</strong></p> <p>这是因为逻辑核心数为 4,我的 CPU 支持超线程或同步多线程 (SMT)。</p> <h2> 工作线程 </h2> <p>在餐厅里,服务员接受订单并将订单交给厨师团队,因为烹饪需要一些时间。如果有清洁桌子或任何其他与服务员相关的工作,那么服务员就会这样做。当订单准备好后,厨师将食物返还给服务员,服务员将这些食物提供给顾客。</p> <p>这与工作线程相关的场景相同。如果出现任何计算量大的任务,例如大规模数据处理、复杂计算或繁重算法,则主线程会将此任务委托给工作线程。该任务由工作线程执行,而不是主线程。</p> <p>*<em>为什么,这有帮助? *</em></p> <p>我们知道 Node JS 事件循环是单线程的,如果这种繁重的计算工作由主线程完成,那么事件循环将被阻塞。如果您使用这些工作线程,那么这些繁重的任务将交给工作线程,工作线程执行这些任务,而不是主线程,因此事件循环不会被阻塞。</p> <p>工作线程可以通过消息传递系统与主线程通信,并且可以使用结构化克隆(深复制)在线程之间发送数据。</p> <p>现在,我们正在尝试模仿工作线程的工作。</p> <p><strong>main.js(主线程)</strong><br> </p> <pre class="brush:php;toolbar:false">Master 12345 is running Worker 12346 is running Worker 12347 is running Worker 12348 is running Worker 12349 is running
worker.js(工作线程)
const { Worker } = require('worker_threads'); function startWorker() { const worker = new Worker('./worker.js'); // Create a worker using worker.js // Listen for messages from the worker worker.on('message', (message) => { console.log('Message from worker:', message); }); // Handle errors in the worker worker.on('error', (error) => { console.error('Worker error:', error); }); // Handle worker exit worker.on('exit', (code) => { console.log(`Worker exited with code ${code}`); }); // Send a message to the worker worker.postMessage({ num: 100 }); } startWorker();
如果数据包含大型结构,它将被深度克隆并传递,这可能会产生一些性能开销。
代码的工作
Worker 类用于生成新线程。
您可以使用worker.postMessage向worker发送数据,并使用worker.on('message',callback)监听消息。
在工作线程中,parentPort 是与主线程通信的主要接口。
您可以监听来自主线程(parentPort.on('message'))的消息并使用parentPort.postMessage发回消息。
输出将是:
const cluster = require('cluster');
现在,您还有一个问题:为什么我们不创建数百个工作线程?
但是,原因是如果您创建的线程多于核心数量,线程将竞争 CPU 时间,导致上下文切换,这会导致成本高昂并降低整体性能。
什么时候应该在 Node.js 中使用集群、工作线程或两者?
1。何时使用工作线程?
- CPU 密集型任务:
涉及大量计算的任务,例如图像/视频处理、数据压缩或加密、机器学习推理、科学计算
- 需要共享内存:
您需要在线程之间有效地共享数据而不重复数据。
- 单核使用情况:
如果您的应用程序只需要在单个进程内扩展,但仍然需要 CPU 密集型任务的并行性。
2.什么时候使用聚类?
- I/O 限制:
任务涉及处理大量客户端请求,例如 Web、服务器、聊天应用程序和 API。集群通过在所有 CPU 核心之间分配请求来帮助水平扩展。
- 孤立的记忆:
您的应用程序不需要在进程之间共享大量数据。
- 多核利用率:
您希望通过生成多个 Node.js 进程来利用所有可用的核心。
3.什么时候同时使用集群和工作线程?
- I/O 密集型 CPU 密集型任务:
应用程序处理 HTTP 请求,但卸载计算密集型任务。示例:网络服务器处理文件上传并执行图像大小调整或视频转码。
- 高可扩展性:
您需要进程级和线程级并行性才能实现高吞吐量。在电子商务网站中,集群可确保多个进程处理传入请求。工作线程处理后台任务,例如生成个性化推荐。
谢谢。
欢迎提出问题或提出任何建议。
如果您发现本文内容丰富,请点赞。
以上是集群和工作线程 - Node JS的详细内容。更多信息请关注PHP中文网其他相关文章!

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

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

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

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。

如何在Quartz中提前发送任务通知在使用Quartz定时器进行任务调度时,任务的执行时间是由cron表达式设定的。现�...


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

Atom编辑器mac版下载
最流行的的开源编辑器

Dreamweaver CS6
视觉化网页开发工具

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

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能