NodeJS感知和控制自身进程的运行环境和状态

 更新时间:2024年01月01日 09:39:36   投稿:yin  
NodeJS可以感知和控制自身进程的运行环境和状态,也可以创建子进程并与其协同工作,这使得NodeJS可以把多个程序组合在一起共同完成某项工作,并在其中充当胶水和调度器的作用,和进程管理相关的API单独介绍起来比较枯燥,这里从一些典型的应用场景出发

NodeJS可以感知和控制自身进程的运行环境和状态,也可以创建子进程并与其协同工作,这使得NodeJS可以把多个程序组合在一起共同完成某项工作,并在其中充当胶水和调度器的作用。和进程管理相关的API单独介绍起来比较枯燥,因此这里从一些典型的应用场景出发,分别介绍一些重要API的使用方法。

如何获取命令行参数

在NodeJS中可以通过process.argv获取命令行参数。但是比较意外的是,node执行程序路径和主模块文件路径固定占据了argv[0]argv[1]两个位置,而第一个命令行参数从argv[2]开始。为了让argv使用起来更加自然,可以按照以下方式处理。

function main(argv) {
    // ...
}

main(process.argv.slice(2));

如何退出程序

通常一个程序做完所有事情后就正常退出了,这时程序的退出状态码为0。或者一个程序运行时发生了异常后就挂了,这时程序的退出状态码不等于0。如果我们在代码中捕获了某个异常,但是觉得程序不应该继续运行下去,需要立即退出,并且需要把退出状态码设置为指定数字,比如1,就可以按照以下方式:

try {
    // ...
} catch (err) {
    // ...
    process.exit(1);
}

如何控制输入输出

NodeJS程序的标准输入流(stdin)、一个标准输出流(stdout)、一个标准错误流(stderr)分别对应process.stdinprocess.stdoutprocess.stderr,第一个是只读数据流,后边两个是只写数据流,对它们的操作按照对数据流的操作方式即可。例如,console.log可以按照以下方式实现。

function log() {
    process.stdout.write(
        util.format.apply(util, arguments) + '\n');
}

如何降权

在Linux系统下,我们知道需要使用root权限才能监听1024以下端口。但是一旦完成端口监听后,继续让程序运行在root权限下存在安全隐患,因此最好能把权限降下来。以下是这样一个例子。

http.createServer(callback).listen(80, function () {
    var env = process.env,
        uid = parseInt(env['SUDO_UID'] || process.getuid(), 10),
        gid = parseInt(env['SUDO_GID'] || process.getgid(), 10);

    process.setgid(gid);
    process.setuid(uid);
});

上例中有几点需要注意:

  • 如果是通过sudo获取root权限的,运行程序的用户的UID和GID保存在环境变量SUDO_UIDSUDO_GID里边。如果是通过chmod +s方式获取root权限的,运行程序的用户的UID和GID可直接通过process.getuidprocess.getgid方法获取。

  • process.setuidprocess.setgid方法只接受number类型的参数。

  • 降权时必须先降GID再降UID,否则顺序反过来的话就没权限更改程序的GID了。

如何创建子进程

以下是一个创建NodeJS子进程的例子。

var child = child_process.spawn('node', [ 'xxx.js' ]);

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

child.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

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

上例中使用了.spawn(exec, args, options)方法,该方法支持三个参数。第一个参数是执行文件路径,可以是执行文件的相对或绝对路径,也可以是根据PATH环境变量能找到的执行文件名。第二个参数中,数组中的每个成员都按顺序对应一个命令行参数。第三个参数可选,用于配置子进程的执行环境与行为。

另外,上例中虽然通过子进程对象的.stdout.stderr访问子进程的输出,但通过options.stdio字段的不同配置,可以将子进程的输入输出重定向到任何数据流上,或者让子进程共享父进程的标准输入输出流,或者直接忽略子进程的输入输出。

进程间如何通讯

在Linux系统下,进程之间可以通过信号互相通信。以下是一个例子。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ]);

child.kill('SIGTERM');

/* child.js */
process.on('SIGTERM', function () {
    cleanUp();
    process.exit(0);
});

在上例中,父进程通过.kill方法向子进程发送SIGTERM信号,子进程监听process对象的SIGTERM事件响应信号。不要被.kill方法的名称迷惑了,该方法本质上是用来给进程发送信号的,进程收到信号后具体要做啥,完全取决于信号的种类和进程自身的代码。

另外,如果父子进程都是NodeJS进程,就可以通过IPC(进程间通讯)双向传递数据。以下是一个例子。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ], {
        stdio: [ 0, 1, 2, 'ipc' ]
    });

child.on('message', function (msg) {
    console.log(msg);
});

child.send({ hello: 'hello' });

/* child.js */
process.on('message', function (msg) {
    msg.hello = msg.hello.toUpperCase();
    process.send(msg);
});

可以看到,父进程在创建子进程时,在options.stdio字段中通过ipc开启了一条IPC通道,之后就可以监听子进程对象的message事件接收来自子进程的消息,并通过.send方法给子进程发送消息。在子进程这边,可以在process对象上监听message事件接收来自父进程的消息,并通过.send方法向父进程发送消息。数据在传递过程中,会先在发送端使用JSON.stringify方法序列化,再在接收端使用JSON.parse方法反序列化。

如何守护子进程

守护进程一般用于监控工作进程的运行状态,在工作进程不正常退出时重启工作进程,保障工作进程不间断运行。以下是一种实现方式。

/* daemon.js */
function spawn(mainModule) {
    var worker = child_process.spawn('node', [ mainModule ]);

    worker.on('exit', function (code) {
        if (code !== 0) {
            spawn(mainModule);
        }
    });
}

spawn('worker.js');

可以看到,工作进程非正常退出时,守护进程立即重启工作进程。

到此这篇关于NodeJS感知和控制自身进程的运行环境和状态的文章就介绍到这了,更多相关NodeJS感知和控制自身进程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • nodejs npm包管理的配置方法及常用命令介绍

    nodejs npm包管理的配置方法及常用命令介绍

    这篇文章主要介绍了nodejs npm包管理的配置方法及常用命令介绍,需要的朋友可以参考下
    2014-06-06
  • Node.js 构建命令行工具之实现 ls 命令的 -a 和 -l 选项

    Node.js 构建命令行工具之实现 ls 命令的 -a 和 

    本文介绍了如何使用Node.js实现一个简单的命令行工具,模仿常用的ls命令,包括其-a和-l参数的功能,文章详细讲解了命令行参数的解析、文件类型的判断、权限信息的处理、文件链接数和修改时间的格式化等步骤,并提供了完整的代码实现
    2024-11-11
  • node.js mongoose index索引操作

    node.js mongoose index索引操作

    在 Mongoose 中,索引(Index)是一种用于提高查询性能的数据结构,它可以加速对数据库中文档的检索操作,本文给大家介绍
    node.js mongoose index索引操作
    ,感兴趣的朋友一起看看吧
    2023-12-12
  • nodejs事件的监听与触发的理解分析

    nodejs事件的监听与触发的理解分析

    这篇文章主要介绍了nodejs事件的监听与触发的理解分析,以实例形式对比分析了nodejs与jQuery关于事件监听的实用技巧,有助于加深对nodejs的理解,需要的朋友可以参考下
    2015-02-02
  • Node.js16.15.1的一个报错以及解决方案分享

    Node.js16.15.1的一个报错以及解决方案分享

    这篇文章主要给大家介绍了关于Node.js16.15.1的一个报错以及解决方案的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-12-12
  • Nodejs极简入门教程(二):定时器

    Nodejs极简入门教程(二):定时器

    这篇文章主要介绍了Nodejs极简入门教程(二):定时器,本文讲解了setTimeout、setInterval、setImmediate及process.nextTick等内容,需要的朋友可以参考下
    2014-10-10
  • 快速查询nodejs版本信息的六种方法

    快速查询nodejs版本信息的六种方法

    Node.js是一款基于Chrome V8引擎的快速、轻量级的JavaScript运行时,随着应用程序规模越来越庞大,Node.js版本的更新也日益频繁,这篇文章旨在帮助开发者们快速查询Node.js版本信息,需要的朋友可以参考下
    2023-11-11
  • Node.js API详解之 vm模块用法实例分析

    Node.js API详解之 vm模块用法实例分析

    这篇文章主要介绍了Node.js API详解之 vm模块用法,结合实例形式分析了Node.js API中vm模块基本功能、函数、使用方法及相关操作注意事项,需要的朋友可以参考下
    2020-05-05
  • node-gyp安装vuetify编译失败gyp ERR的问题及解决

    node-gyp安装vuetify编译失败gyp ERR的问题及解决

    这篇文章主要介绍了node-gyp安装vuetify编译失败gyp ERR的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • node.js实现简单的压缩/解压缩功能示例

    node.js实现简单的压缩/解压缩功能示例

    这篇文章主要介绍了node.js实现简单的压缩/解压缩功能,结合实例形式分析了node.js实现本地文件与服务器端压缩/解压缩相关操作技巧,需要的朋友可以参考下
    2019-11-11

最新评论