Node.js - 扩展应用程序



Node.js 应用程序的可伸缩性是指它能够处理服务器上不断增加的工作负载,并从客户端接收更多的请求。Node.js应用程序可以利用子进程来解决此问题。子进程是 Node.js运行时的一个独立实例,可以由主进程生成和管理。这种生成的子进程可以并行执行特定任务,从而提高了应用程序的整体性能和可伸缩性。

child_process模块是运行时的核心模块之一Node.js。该模块提供了用于创建、管理子进程以及与子进程通信的各种方法,尤其是在基于多核 CPU 的系统上。

子进程始终有三个流:child.stdin、child.stdout 和 child.stderr。这些流可以与父进程的流共享。

child_process模块,主要有以下三种方式来创建子进程。
  • exec − child_process.exec 方法在 shell/控制台中运行命令并缓冲输出。
  • spawn - child_process.spawn 使用给定命令启动一个新进程。
  • fork − child_process.fork 方法是 spawn() 的特例,用于创建子进程。

exec() 方法

child_process.exec 方法在 shell 中运行命令并缓冲输出。它具有以下签名 -


 child_process.exec(command[, options], callback)

参数

  • command - 要运行的命令,带有空格分隔的参数。
  • options − cwd- 子进程的当前工作目录,env - 环境键值对
    • encoding − 编码字符串 (默认: 'utf8')
    • shell - Shell执行命令(默认:UNIX上的“/bin/sh”,Windows上的“cmd.exe”,shell应理解UNIX上的-c开关或Windows上的/s /c。在 Windows 上,命令行解析应与 cmd.exe 兼容。
    • timeout − 默认值:0
    • maxBuffer − 默认值:200*1024
    • killSignal − 默认值: 'SIGTERM'
    • uid - 设置进程的用户身份。
    • gid - 设置进程的组标识。
    • callback - 具有三个参数的函数 error、stdout 和 stderr,当进程终止时,它们将与输出一起调用。
exec() 方法返回一个具有最大大小的缓冲区,并等待进程结束并尝试一次返回所有缓冲数据。

让我们创建两个名为 child.js 和 main.js 的 js 文件 -

文件:child.js


console.log("Starting Child Process-" + process.argv[2]);
console.log("Child Process-" + process.argv[2] + " executed." );

文件:main.js


const fs = require('fs');
const child_process = require('child_process');

for(var i=0; i<3; i++) {
	 	var childprocess = child_process.exec('node child.js '+i,function	
	 	 	 (error, stdout, stderr) {
	 	 		
	 	 	 if (error) {
	 	 	 	 	console.log(error.stack);
	 	 	 	 	console.log('Error code: '+error.code);
	 	 	 	 	console.log('Signal received: '+error.signal);
	 	 	 }
	 	 	 console.log('stdout: ' + stdout);
	 	 	 console.log('stderr: ' + stderr);
	 	});

	 	childprocess.on('exit', function (code) {
	 	 	 console.log('Child process exited with exit code '+code);
	 	});
}

现在运行main.js以查看结果 -

Child process exited with exit code 0
stdout: Starting Child Process-0
Child Process-0 executed.

stderr:
Child process exited with exit code 0
stdout: Starting Child Process-1
Child Process-1 executed.

stderr:
Child process exited with exit code 0
stdout: Starting Child Process-2
Child Process-2 executed.

stderr:

spawn() 方法

child_process.spawn 方法使用给定的命令启动一个新进程。


 child_process.spawn(command[, args][, options])

第一个参数是子进程要运行的命令。可以将一个或多个参数传递给它。options 参数可能具有以下一个或多个属性 -

  • cwd (String) 子进程的当前工作目录。
  • env(Object)环境键值对。
  • stdio (Array) String Child 的 stdio 配置。
  • customFds (Array) 已弃用的文件描述符,供子项用于 stdio。
  • detached(Boolean) 子项将成为进程组组长。
  • uid(Number)设置进程的用户标识。
  • gid (Number) 设置进程的组标识。

spawn() 方法返回流 (stdout &stderr),当进程返回大量数据时,应使用它。spawn() 在进程开始执行后立即开始接收响应。

与前面的示例一样,创建 child.js 和 main.js 文件。

child.js


console.log("Starting Child Process-" + process.argv[2]);
console.log("Child Process-" + process.argv[2] + " executed." );

main.js


const fs = require('fs');
const child_process = require('child_process');

for(var i=0; i<3; i++) {
var childprocess = child_process.spawn('node', ['child.js', i]);

	 	childprocess.stdout.on('data', function (data) {
	 	 	 console.log('stdout: ' + data);
	 	});

	 	childprocess.on('exit', function (code) {
	 	 	 console.log('Child process exited with exit code '+code);
	 	});
}

输出

stdout: Starting Child Process-0

stdout: Child Process-0 executed.

Child process exited with exit code 0
stdout: Starting Child Process-1

stdout: Child Process-1 executed.

stdout: Starting Child Process-2

stdout: Child Process-2 executed.

Child process exited with exit code 0
Child process exited with exit code 0

fork() 方法

child_process.fork 方法是 spawn() 创建 Node 进程的特例。它具有以下语法 -


 child_process.fork(modulePath[, args][, options])

参数

第一个参数是子项要调整的模块。您可以将其他参数传递给模块。这些选项与 spawn() 方法中的选项相同。

与前面的示例一样,创建 child.js 和 main.js 文件。

child.js


console.log("Starting Child Process-" + process.argv[2]);
console.log("Child Process-" + process.argv[2] + " executed." );

main.js


const fs = require('fs');
const child_process = require('child_process');

for(var i=0; i<3; i++) {
	 	var childprocess = child_process.fork("child.js", [i]);		 	

	 	childprocess.on('close', function (code) {
	 	 	 console.log('child process exited with code ' + code);
	 	});
}

输出

Starting Child Process-0
Child Process-0 executed.
Starting Child Process-2
Child Process-2 executed.
Starting Child Process-1
Child Process-1 executed.
child process exited with code 0
child process exited with code 0
child process exited with code 0

execFile() 方法

child_process.execFile() 函数类似于 exec() 方法,不同之处在于它默认不生成 shell。它比 exec() 稍微高效一些,因为指定的可执行文件直接作为新进程生成。

语法


child_process.execFile(command [, args][, options][, callback])

参数

  • command − 接受一个字符串,该字符串指定要运行的命令的名称或路径。
  • args - 字符串参数列表。
  • options - 一些可用的选项是cwd,env,编码,shell,超时等
  • callback − 当进程终止时调用回调函数。此函数的参数分别是 error、stdout 和 stderr。