node 进程管理

node的一个最大特性就是单线程,单线程带来的好处是不用像多线程编程那样去考虑状态的同步问题,也不用去担心出现死锁,也没有线程上下文所带来的性能的开销。

同时也带来了一些问题,比如无法充分利用的多核CPU,线程会阻塞的问题。

  1. process对象。
  2. child_process对象。
  3. cluster模块。

process 对象

process模块允许你获得或者修改当前node进程的设置,不想其他的模块,process是一个全局进程(node主进程),你可以直接通过process变量直接访问它。
在nodejs使用中,有一种情况比如:函数不存在、语法错误什么的,整个nodejs运行断掉,程序停止。

process模块提供了uncaughtException 事件用于处理这个问题。

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});
setTimeout(function () {
  console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
复制代码

process 属性

process.version://包含当前node实例的版本号;

process.platform://列举node运行的操作系统的环境,只会显示内核相关的信息,如:linux2, darwin,而不是“Redhat ES3” ,“Windows 7”,“OSX 10.7”等;

process.uptime()://包含当前进程运行的时长(秒);

process.getgid(), process.setgid()://获取或者设置group id;

process.getuid(), process.setuid()://获取或者设计user id;

process.pid://获取进程id;

process.title://设置进程名称;

process.execPath://当前node进程的执行路径,如:/usr/local/bin/node;

process.cwd()://当前工作目录;

process.memoryUsage()://node进程内存的使用情况,rss代表ram的使用情况,vsize代表总内存的使用大小,包括ram和swap;

process.heapTotal,process.heapUsed://分别代表v8引擎内存分配和正在使用的大小。

process.env 查看环境变量
复制代码
process.stdin.resume(); //这句话是为了不让控制台推出
    process.on('SIGINT', function () { //SIGINT这个信号是系统默认信号,代表信号中断,就是ctrl+c
});
复制代码

自定义监听process事件on

process.on('SIGUSR1', function (d) { //这里监听 SIGUSR1 事件
     console.log('Bye-'+d); //这里将输出Bye-Bye,然后推出进程
     process.exit(0);
   });
 process.emit('SIGUSR1', 'Bye'); //利用emit触发SIGUSR1,然后传参数为Bye
复制代码
console.log = function (d) {
 process.stdout.write(d + '\n');
};
复制代码
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function (chunk) {
  process.stdout.write('data: ' + chunk);
});
process.stdin.on('end', function () {
  process.stdout.write('end');
});
复制代码

child_process属性

  1. 可以实现创建多进程,以利用单机的多核计算资源。
  2. 可以在程序中直接创建子进程,并使用主进程和子进程之间实现通信,等到子进程运行结束以后,主进程再用回调函数读取子进程的运行结果。
  3. child_process.exec()
  4. child_process.spawn()

process.exec 执行系统命令

var cp = require('child_process');
cp.exec('ls -l', function(e, stdout, stderr) {
  if(!e) {
    console.log(stdout);
    console.log(stderr);
  }
});
复制代码

自定义 options

var options = { 
    encoding: 'utf8',   // I/O流的编码格式;
    timeout: 0,            // 进程超时时间;
    maxBuffer: 200 * 1024,  //  当时间或者缓冲区超限时终止进程的信号;
    killSignal: 'SIGTERM',    //  stdout或stderr可增长的最大值;
    setsid: false,                   //  决定在进程中是否创建一个新的会话;
    cwd: null,         //  进程的初始工作目录,为null时表示使用node的当前工作目录;
    env: null        //   进程的环境变量。
};
var cp = require('child_process');
cp.exec('ls -l', options, function(e, stdout, stderr) {
  if(!e) {
    console.log(stdout);
    console.log(stderr);
  }
});
复制代码

process.spawn

var cp = require('child_process');
var cat = cp.spawn('cat');
cat.stdout.on('data', function(d) {
  console.log(d.toString());
});
cat.on('exit', function() {
  console.log('kthxbai');
});
cat.stdin.write('hello world!');
cat.stdin.end();
***child_process.spawn( )比child_process.exec( )更加强大和灵活
复制代码

cluster

cluster模块可以轻松实现运行在同一机器不同进程上的TCP或HTTP服务器集群。它们仍使用相同的底层套接字,从而在相同的IP地址和端口组合上处理请求。

fork: //当新的工作进程已经被派生时发出。callback函数接收worker对象作为唯一的参数。function(Worker)

online: //当新的进程发回一消息,表明它已经启动时发出。callback同上。

listening: //当工作进程调用listen()开始监听端口时发出。callback:fucntion(Worker,address)

disconnect: //当IPC通道被切断时发出。如服务器调用worker.disconnect()的时候。callback:function(Worker)

exit: //在Worker对象已断开时发出。callback:function(Worker,code,signal)

setup: //在setupMaster()被首次调用时发出。

属性和方法:

settings: //包含exec(工作进程的javascript文件)、args(传递的参数数组)、silent(断开工作进程的IPC机制)属性值,用于建立集群

isMaster: //判断当前进程是否是主进程

isWorker: //判断当前进程是否是工作进程

setupMaster([settings]): //启动主进程

disconnect([callback]): //断开工作进程的IPC机制,并关闭句柄,当断开连接完成时回调

worker: //引用在工作进程的当前Worker对象

workers://包含Worker对象,可以通过标识从主进程引用它们。cluster.workers[workerId]
复制代码
var cluster = require('cluster');
var http = require('http');
if (cluster.isMaster) {
  cluster.on('fork', function(worker) {
    console.log("Worker " + worker.id + " created");
  });
  cluster.on('listening', function(worker, address) {
    console.log("Worker " + worker.id +" is listening on " + 
                address.address + ":" + address.port);
  });
  cluster.on('exit', function(worker, code, signal) {
    console.log("Worker " + worker.id +" Exited");    
  });
  cluster.setupMaster({exec:'cluster_worker.js'});  //图例二js demo
  var numCPUs = require('os').cpus().length;
  for (var i = 0; i < numCPUs; i++) {
    if (i>=4) break;
    cluster.fork();
  }
  Object.keys(cluster.workers).forEach(function(id) {
    cluster.workers[id].on('message', function(message){
      console.log(message);
    });
  });
}
复制代码
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`主进程 ${process.pid} 正在运行`);

  // 衍生工作进程。
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
  });
} else {
  // 工作进程可以共享任何 TCP 连接。
  // 在本例子中,共享的是一个 HTTP 服务器。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hellow world \n');
  }).listen(8000);

  console.log(`工作进程 ${process.pid} 已启动`);
}
复制代码
var cluster = require('cluster');
var http = require('http');
if (cluster.isWorker) {
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("Process " + process.pid + " says hello");
    process.send("Process " + process.pid + " handled request");
  }).listen(8080, function(){
    console.log("Child Server Running on Process: " + process.pid);    
  });
}
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值