深入理解NodeJS 多进程和集群

yizhihongxing

深入理解 Node.js 多进程和集群攻略

本文将介绍 Node.js 多进程和集群的相关知识,包括多进程和集群的概念、实现方式和使用场景等。同时,本文将提供两个示例以更好地说明多进程和集群对 Node.js 应用的影响。

多进程和集群的概念

多进程

Node.js 中的多进程指的是利用多个进程并行处理任务。多进程对于 CPU 密集型应用十分有用,因为 Node.js 在 处理 CPU 密集型任务时存在单线程的瓶颈,无法充分利用 CPU 资源。

Node.js 提供了 child_process 模块,允许创建多个子进程来执行代码。这些子进程可以在主进程和其他子进程之间进行通信,从而组成了多进程应用程序。

集群

集群是用于分布式系统的一组计算机。在 Node.js 中,集群表示将应用程序扩展到多个进程和服务器上,从而增加了系统的可扩展性和可靠性。集群可以将一个应用程序部署在多个计算机上,同时使用负载均衡技术来均衡不同进程之间的工作量,从而达到更好的性能和稳定性。

Node.js 提供了 cluster 模块,可用于创建一个集群。集群会启动多个 Node.js 进程,并将每个进程分配到不同的 CPU 核心上。这些进程可以在同一台计算机上或不同的计算机上运行,并通过负载均衡机制来分发连接。

实现方式

多进程实现方式

Node.js 提供了三种多进程实现方式:

  1. fork()

fork() 允许我们在主进程中创建一个子进程,子进程可以运行与主进程不同的代码,且子进程会共享主进程的 I/O 资源和环境变量等信息。子进程和主进程之间的通信可以通过 ChildProcess 对象(即返回值)实现。

```javascript
const { fork } = require('child_process');

const childProcess = fork('./child.js');

// 在父子进程之间传递消息
childProcess.send('Hello from parent');
childProcess.on('message', (msg) => {
console.log(Received message from child: ${msg});
});
```

  1. exec()

exec() 允许我们在子进程中运行 shell 命令,它与 fork() 不同的是,执行的是外部命令而不是 node.js 脚本文件,因此它运行的是一个不同的进程,并且不能直接访问在主进程中定义的变量等。

```javascript
const { exec } = require('child_process');

exec('ls -lh /usr', (error, stdout, stderr) => {
if (error) {
console.error(exec error: ${error});
return;
}
console.log(stdout: ${stdout});
console.log(stderr: ${stderr});
});
```

  1. spawn()

spawn() 允许我们在一个新的进程中运行命令。它与 exec() 的区别在于,exec() 执行的是一个 shell 命令,而 spawn() 可以直接执行一个可执行文件,并将他的标准输入/输出/错误流等信息返回主进程,供后续处理。

```javascript
const { spawn } = require('child_process');

const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
console.log(${data});
});

bat.stderr.on('data', (data) => {
console.error(${data});
});

bat.on('close', (code) => {
console.log(child process close all stdio with code ${code});
});
```

集群实现方式

要使用 Node.js 集群,需要使用 cluster 模块。具体的实现步骤如下:

  1. 在主进程中创建多个子进程:

```javascript
const cluster = require('cluster');

if (cluster.isMaster) {
console.log(Master ${process.pid} is running);

 const cpuCount = require('os').cpus().length;

 for (let i = 0; i < cpuCount; i++) {
   cluster.fork();
 }

 cluster.on('exit', (worker, code, signal) => {
   console.log(`worker ${worker.process.pid} died`);
 });

} else {
console.log(Worker ${process.pid} started);
}
```

  1. 在子进程中运行应用程序:

```javascript
const http = require('http');

const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello world!\n');
});

server.listen(8000);

console.log(Worker ${process.pid} started);
```

使用场景

多进程和集群应该在哪些情况下使用呢?下面我们将介绍一些常见场景。

多进程的使用场景

多进程适用于 CPU 密集型应用,因为 Node.js 在处理 CPU 密集型任务时存在单线程的瓶颈,多进程可以充分利用 CPU 资源。例如计算圆周率的程序。

// 生成一个随机数
function randomNum() {
  return Math.floor(Math.random() * 1000000000);
}

function calculation() {
  let pi = 0,
    n = 1000000000,
    w = 1.0 / n,
    i = 0;
  for (; i < n; i++) {
    let x = w * (i + 0.5);
    pi += w * 4.0 / (1.0 + x * x);
  }
  return pi;
}

console.time(`single process`);
const pi = calculation();
console.timeEnd(`single process`);
console.log(`pi: ${pi}`);

const processes = 8;

console.time(`multi processes`);
const childProcesses = [];
for (let i = 0; i < processes; i++) {
  const childProcess = fork('./child.js');
  childProcess.on('message', (msg) => {
    console.log(`Received message from child: ${msg}`);
  });
  childProcess.send(randomNum());
}

// 计算每个子进程的 Pi 值
let result = 0;
for (let i = 0; i < processes; i++) {
  let message = receiveMsg();
  console.log(message);
  result += message;
}

console.timeEnd(`multi processes`);
console.log(`pi: ${result / processes}`);

集群的使用场景

集群可以使 Node.js 应用程序的性能和可用性更高。如果您的应用程序需要同时处理大量请求,并且可能会在处理这些请求时出现延迟或错误,那么集群就是一个很好的选择。

最常见的使用场景是 Web 应用程序的负载均衡,例如高流量的电子商务网站。通过使用集群,可以将 HTTP 请求分散到多个进程或服务器上,从而降低每个进程的负载,同时提高整个应用程序的性能和可靠性。

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);

  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello, world!');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}

示例说明

示例 1:多进程 parallelism

该示例演示了利用多进程并行处理任务可以大大缩短运行时间,从而提高性能。

运行时,该示例会生成一个随机整数并使用 fork() 生成 8 个子进程计算该整数的 PI 值。 测试结果表明,并行处理任务的总时间要比单个进程处理任务的时间短得多。

示例 2:集群的负载均衡

该示例演示了利用集群可以实现负载平衡,从而增强 Web 应用程序的性能和可靠性。

运行时,该示例会向 8000 端口发出 100 个 HTTP 请求,这些请求将会分配到多个子进程或服务器上。测试结果表明,多个子进程或服务器处理请求的总时间要比单个进程或服务器处理请求的时间短得多。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解NodeJS 多进程和集群 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • Node.js用readline模块实现输入输出

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境。在Node.js环境中,可以使用readline模块实现输入输出。下面我来详细讲解如何使用readline模块。 readline模块概述 readline模块是Node.js核心模块之一,用于读取用户输入和输出文本。对于使用Node.js进行开发的应用程序,readline模块可…

    node js 2023年6月8日
    00
  • 如何将HTML字符转换为DOM节点并动态添加到文档中详解

    将HTML字符转换为DOM节点并动态添加到文档中,可以通过innerHTML属性、createRange和createContextualFragment方法、以及DOMParser接口来实现。 使用innerHTML属性 可以通过innerHTML属性将HTML字符串转换为DOM节点,并将这些节点添加到文档中。 // 获取包含HTML代码的字符串 cons…

    node js 2023年6月8日
    00
  • nodejs实例解析(输出hello world)

    Node.js是基于Chrome V8引擎开发的运行在服务器端的JavaScript运行环境,提供了一种轻量级、高效、可扩展的方式来搭建网络应用程序。下面是如何使用Node.js输出“hello world”的攻略。 准备工作 在开始之前,请确保已经安装了Node.js。可以在命令行中输入以下命令检查是否已经安装: node -v 如果已经安装,则会输出安装…

    node js 2023年6月8日
    00
  • Node.js内置模块events事件监听发射详解

    Node.js 内置模块 events 为发布-订阅模式提供了基础。该模块提供了两个类:EventEmitter 和 Class。EventEmitter 是所有事件侦听器类的父类,而 Class 则使其更容易地进行继承。 EventEmitter 类 EventEmitter 类提供了一些方法来操作事件: on(eventName, listener) -…

    node js 2023年6月8日
    00
  • Node.js实战之Buffer和Stream模块系统深入剖析详解

    Node.js实战之Buffer和Stream模块系统深入剖析详解 什么是Buffer和Stream Buffer是用于处理二进制数据的模块,它将数据存储在内存中的固定大小的缓冲区中,可以快速地分配和释放内存并进行快速且高效的读写操作。 Stream则是一种处理数据流的模块,用于处理实时数据源如网络、文件等产生的数据。Stream可以将数据分成小块,这样就可…

    node js 2023年6月8日
    00
  • 使用Vue.js和MJML创建响应式电子邮件

    下面是使用Vue.js和MJML创建响应式电子邮件的完整攻略: 为什么选择Vue.js和MJML? 在创建响应式电子邮件时,我们需要考虑邮件客户端的兼容性和显示效果。Vue.js是一个流行的JavaScript框架,可以方便地处理逻辑。而MJML是一个专门为电子邮件设计的开源标记语言,可以处理邮件的布局和样式。 开发流程 创建一个Vue.js项目:首先需要你…

    node js 2023年6月8日
    00
  • 解决Node.js mysql客户端不支持认证协议引发的问题

    问题描述 在使用 Node.js MySQL 客户端时,可能会遇到以下错误: Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client 这个错误发…

    node js 2023年6月8日
    00
  • vuepress打包部署踩坑及解决

    下面详细讲解“vuepress打包部署踩坑及解决”的完整攻略。 综述 VuePress 是一个基于 Vue 的静态网站生成器,它可以用来快速搭建文档网站或博客等。但是,在实际的开发过程中,我们有可能会遇到打包或部署时的问题,本文将对这些问题进行详细的解答和指导。 VuePress 打包 安装依赖 在打包之前,我们需要安装相关依赖。在终端中输入以下命令: np…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部