简介

  • NodeJS可以感知和控制自身进程的运行环境和状态,也可以创建子进程并与其协同工作,这使得NodeJS可以把多个程序组合在一起共同完成某项工作,并在其中充当胶水和调度器的作用

常用API

Process

  • 任何一个进程都有启动进程时使用的命令行参数,有标准输入标准输出,有运行权限,有运行环境和运行状态。
  • 在NodeJS中,可以通过process对象感知和控制NodeJS自身进程的方方面面。另外需要注意的是,process不是内置模块,而是一个全局对象,因此在任何地方都可以直接使用。

Child Process

  • 使用child_process模块可以创建和控制子进程。该模块提供的API中最核心的是.spawn,其余API都是针对特定使用场景对它的进一步封装,算是一种语法糖。

Cluster

  • cluster模块是对child_process模块的进一步封装,专用于解决单进程NodeJS Web服务器无法充分利用多核CPU的问题。
  • 使用该模块可以简化多进程服务器程序的开发,让每个核上运行一个工作进程,并统一通过主进程监听端口和分发请求。

应用场景

如何获取命令行参数

  • 可以通过process.argv获取命令行参数。
  • 但node执行程序路径和主模块文件路径固定占据了argv[0]和argv[1]两个位置,而第一个命令行参数从argv[2]开始。
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
  • 第一个是只读数据流,后边两个是只写数据流,对它们的操作按照对数据流的操作方式即可。
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权限的,运行程序的用户的UIDGID保存在环境变量SUDO_UIDSUDO_GID里边。

  • 如果是通过chmod +s方式获取root权限的,运行程序的用户的UIDGID可直接通过process.getuidprocess.getgid方法获取;process.setuidprocess.setgid方法只接受number类型的参数。

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

如何创建子进程

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');
  • 工作进程非正常退出时,守护进程立即重启工作进程

node.js整理 05进程管理的更多相关文章

  1. Node.js 中的进程和线程

    线程和进程是计算机操作系统的基础概念,在程序员中属于高频词汇,那如何理解呢?Node.js 中的进程和线程又是怎样的呢? 一.进程和线程 1.1.专业性文字定义 进程(Process),进程是计算机中 ...

  2. node.js整理 07例子

    需求 一个简单的静态文件合并服务器,该服务器需要支持类似以下格式的JS或CSS文件合并请求. http://assets.example.com/foo/??bar.js,baz.js 在以上URL中 ...

  3. Node的安装和进程管理

    安装nvm git clone https://github.com/creationix/nvm.git source nvm/nvm.sh 安装node nvm install 6.14.4(版本 ...

  4. 在Windows平台上安装Node.js及NPM模块管理

    1. 下载Node.js官方Windows版程序:http://nodejs.org/#download    从0.6.1开始,Node.js在Windows平台上提供了两种安装方式,一是.MSI安 ...

  5. node.js中process进程的概念和child_process子进程模块的使用

    进程,你可以把它理解成一个正在运行的程序.node.js中每个应用程序都是进程类的实例对象. node.js中有一个 process 全局对象,通过它我们可以获取,运行该程序的用户,环境变量等信息. ...

  6. node.js初识05

    小项目,需求,通过url来查询学生学号和老师的编号 05.js var http = require("http"); var server = http.createServer ...

  7. node.js中npm包管理工具

    现在安装node.js,默认就会帮我们装上了npm包管理工具,npm主要用来下载,安装,管理第三方模块. 创建一个包描述文件: npm init [-y] 查看包的信息 npm info <pa ...

  8. (转)在Windows平台上安装Node.js及NPM模块管理

    本文转载自:http://www.cnblogs.com/seanlv/archive/2011/11/22/2258716.html 之前9月份的时候我写了一篇关于如何在Windows平台上手工管理 ...

  9. linux系统添加环境变量,node.js forever 守护进程添加环境变量

    1.node.js 守护进程组件 forever 安装 npm install forever -g 安装完成后截图: 2.安装完成后在控制台输入 forever 出现 -bash: forever: ...

随机推荐

  1. Hibernate类中集合的映射

    1 pojo类集合属性的映射 在pojo类中定义集合属性. 1.1  List集合属性的映射 package org.guangsoft.pojo; import java.util.List; pu ...

  2. Stanford大学机器学习公开课(二):监督学习应用与梯度下降

    本课内容: 1.线性回归 2.梯度下降 3.正规方程组   监督学习:告诉算法每个样本的正确答案,学习后的算法对新的输入也能输入正确的答案   1.线性回归 问题引入:假设有一房屋销售的数据如下: 引 ...

  3. 求sqrt()底层效率问题(二分/牛顿迭代)

    偶然看见一段求根的神代码,于是就有了这篇博客: 对于求根问题,通常我们可以调用sqrt库函数,不过知其然需知其所以然,我们看一下求根的方法: 比较简单方法就是二分咯: 代码: #include< ...

  4. php 删除文件夹

    <?php // ./tp // ./tp/Public function deldir($dirname) { if(!file_exists($dirname)) { die("文 ...

  5. ASP.NET Web Api 实现数据的分页(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3542608.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能 ...

  6. win10下安装Ubuntu + 修复Ubuntu引导

    如何在已安装 Windows 10 的情况下安装 Linux(Ubuntu 15.04)双系统? - Microsoft Windows - 知乎http://www.zhihu.com/questi ...

  7. Delphi中的异常处理

    转载:http://www.cnblogs.com/doit8791/archive/2012/05/08/2489471.html 以前写Delphi程序一直不注意异常处理,对其异常处理的机制总是一 ...

  8. 那些年,我们在Django web开发中踩过的坑(一)——神奇的‘/’与ajax+iframe上传

    一.上传图片并在前端展示 为了避免前端整体刷新,我们采用ajax+iframe(兼容所有浏览器)上传,这样用户上传之后就可以立即看到图片: 上传前: 上传后: 前端部分html: <form s ...

  9. n的阶乘高精度算法【阶乘】

    C语言实验——求阶乘(循环结构) Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 题目链接:http://acm.sdut.edu ...

  10. 构造方法 static 块 {}块 执行顺序

    package com.test.innerclass; public class HelloB extends HelloA { public HelloB() { System.out.print ...