关于node.js的进程管理
如果是单纯的运行一个node进程,那会比较简单,例如:
node ./example.js
但是一般来说,当我们运行一个node进程之后,我们可能希望对这个进程进行更多的管理,例如,当node程序是一个server服务时,我们就有更多的需求。
例如:
1.服务挂掉的时候自动重启。
2.列出所有服务,包括服务的信息。
3.能够重启/终止某个服务。
4.为服务的运行记录日志。
1.服务挂掉的时候自动重启。
对于这个需求,我们需要做的是把服务进程当做一个子进程来运行,当子进程不幸挂了,父进程将其重启,例如:
var spawn = require('child_process').spawn;
var cp = spawn(process.execPath,['./example.js']);
cp.on('exit',function(){
//restart
});
假设父进程程序名为pro_a,那么通过父进程启动一个子程序会是这样:
pro_a ./example.js
传入子程序名,由父程序执行。
这样相当于pro_a程序管理子程序的执行:

2.列出所有服务,包括服务的信息。
假设我们执行example.js之后,还有多个程序需要执行,每个程序都使用pro_a程序来启动:
pro_a ./example.js
pro_a ./server.js
pro_a ./other.js
情况变成这样:

如上图,多个pro_a进程对应开启的多个不同子程序的进程。
这时候问题来了,我们希望知道所有用pro_a启动的子进程的进程信息,要怎么做呢?
例如:
pro_a -l //列出所有子进程信息
这时候需求就转变成:新的pro_a进程需要和其他pro_a进程通信,并获取其他pro_a进程运行的子进程的信息。
对于UNIX的跨进程通信,有几种方式,由于这里不同进程在同一个机器中,因此我们这里采用UNIX domain socket的方式(不用经过网卡),让在不同pro_a进程间进行通信。
使用这种方式,我们需要做的是pro_a进程每次创建子进程的时候,启用一个server,并监听对应的sock文件,那么当心的pro_a进程启动之后,就可以通过遍历所有sock文件并对有效sock文件进行连接,从而能够和不同pro_a进程之间进行消息的通信。
例如:
创建子进程的pro_a:
var net = require('net');
//使用UNIX domain socket
var server = net.createServer(function(socket){
socket.setEncoding('UTF8');
socket.on('data',function(){
//收到消息后,向请求方发送子进程相关信息
socket.write(JSON.stringify({
pid:child_process.pid
//...
}));
});
});
server.listen(socketPath + 'resume_' + Date.now() + '.sock');
这样每个pro_a进程创建子进程之后,都会对应产生一个sock文件:

对于新的pro_a进程,第一步是获取所有sock文件,并进行连接:
var getAllSocketFiles = function(){
var socketFiles;
try{
socketFiles = fs.readdirSync(socketPath);
}
catch(ex){
if(ex.code == 'ENOENT'){
fs.mkdirSync(socketPath);
}
socketFiles = fs.readdirSync(socketPath);
}
return socketFiles;
};
针对每个sock文件,创建socket进行连接,并发送消息请求:
var socket = new net.Socket();
socket.setEncoding('UTF8'); socket.connect(this.socketName,function(){
socket.write(JSON.stringify({
//请求对应的子进程信息
}))
}); socket.on('data',function(){
data = JSON.parse(data);
//获得对应子进程信息
});

这样pro_a进程就能从其他pro_进程中获取到信息。
3.能够重启/终止某个服务。
由于我们设置了子程序在挂掉后会自动重启,因此我们需要增加一个命令让程序在需要时能正常关闭,例如:
pro_a -s 1140 //强制终止掉进程号为1140的子进程
此时该pro_a进程需要连接所有其他pro_a进程并获取他们的子进程信息(就像上面-l那样),然后筛选出pid未1140的子进程,再次通过socket发送关闭指令,对应的server接收到关闭指令后把其子进程kill掉。

4.为服务的运行记录日志。
这个只需要pro_a监听子进程的事件,并实时写入log文件就ok了。并且我们可以通过命令让心的pro_a进程能够查看某个其他pro_a进程中子进程的log,例如:
pro_a -L 1130 // 查看1130的子进程的log
原理和3相似,获取所有pro_a进程信息,筛选出pid为1130的子进程,socket发送获取log的指令,对应server把log信息返回。
我把以上pro_a的功能以及更多其他功能封装成一个叫Resume.js的程序放倒github上,有兴趣的同学可以看看:
https://github.com/csonlai/Resume.js
其中包含了上面功能的实现源码。我们可以通过Resume.js进行简单的node进程管理。
欢迎围观,转载请标明出处:
http://www.cnblogs.com/Cson/p/4069868.html
关于node.js的进程管理的更多相关文章
- Node.js的进程管理
众所周知Node基于V8,而在V8中JavaScript是单线程运行的,这里的单线程不是指Node启动的时候就只有一个线程,而是说运行JavaScript代码是在单线程上,Node还有其他线程,比如进 ...
- 4.Node.js 微信消息管理
一.写在前面的话 当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应. 消息推送也是 ...
- Node.js的安装以及Node.js的模块管理
索引: Node.js的安装以及Node.js的模块管理Node.js开发环境搭建以及对ES6的支持Node.js构建Vue.js项目Vue.js单文件组件的开发基于Vue.js的UI组件(Eleme ...
- 使用yarn代替npm作为node.js的模块管理器
使用yarn代替npm作为node.js的模块管理器 转 https://www.jianshu.com/p/bfe96f89da0e Fast, reliable, and secure d ...
- 90%的人都不知道的Node.js 依赖关系管理(下)
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文参考:https://dzone.com/articles/node-dependency-manage ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- nade.js(一)进程管理
简介 process是一个全局内置对象,可以在代码中的任何位置访问此对象,这个对象代表我们的node.js代码宿主的操作系统进程对象. 使用process对象可以截获进程的异常.退出等事件,也可以获取 ...
- Node.js 安装与管理
一.node安装 Windows下,官网下载 Node.js 安装包,运行安装即可, 安装成功后,可查看版本号 node -v 二.npm npm 是 node 包管理工具,随同node一起安装,安装 ...
- node.js守护进程问题的解决
最近自己写了一个node.js来读取redis数据,编写完成后按理来说加& 应该是有效的 nohup node redis.js & 但是每次关闭终端后这个进程就自动停止了,百度了下 ...
随机推荐
- Yarn 安装 on centos7
本文演示如何在CentOS7上安装Yarn.注意这个Yarn是Js包管理器,不是Hadoop的资源调度器. 1 准备工作 1.1 浏览器访问安装包下载地址: https://github.com/ya ...
- OneAPM大讲堂 | Metrics, Tracing 和 Logging 的关系
[编者按]这是在 OpenTracing 和分布式追踪领域内广受欢迎的一片博客文章.在构建监控系统时,大家往往在这几个名词和方式之间纠结. 通过这篇文章,作者很好的阐述了分布式追踪.统计指标与日志之间 ...
- [20171120]关于INBOUND_CONNECT_TIMEOUT设置.txt
[20171120]关于INBOUND_CONNECT_TIMEOUT设置.txt --//上午翻看以前我的发的帖子,发现链接:http://www.itpub.net/thread-2066758- ...
- sql server自定义函数学习笔记
sql server中函数分别有:表值函数.标量函数.聚合函数.系统函数.这些函数中除系统函数外其他函数都需要用户进行自定义. 一.表值函数 简单表值函数 创建 create function fu_ ...
- 洗礼灵魂,修炼python(58)--爬虫篇—【转载】urllib3模块
urllib3 1.简介 urllib3相比urllib,urlib2,又有些一些新的功能,可以实现很多东西,而这个模块有点特殊的是,并且还可以同时存在于python2和python3,但说实话,用的 ...
- python第二十九天-----继续学习第三模块——前几天旅行去了
subprocess模块 import subprocess subprocess.getstatusoutput('dir')#接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结 ...
- domain or business logic
Here are a few of the questions you should ask when writing business logic: ¡Do you fully understand ...
- windows下更改Mac地址
方法一.在桌面上的“网上邻居”图标上单击右键,选择“属性”,在弹出的“网络连接”的对话框中,在“本地连接”图标上单击右键,选择“属性”,会弹出一个“本地连接属性”的对话框,单击“配置”按钮,选择“高级 ...
- IE浏览器打不开网页的解决方法
前阵子一下子安装了很多软件,后来使用IE游览器的时候,莫名其妙的打不开网页,虽然用其他浏览器(比如谷歌.火狐)可以正常浏览网页,但是由于很多软件内嵌页面都会调用Windows的IE浏览器来加载,所以I ...
- 从源码的角度分析List与Set的区别
很多时候我们在讨论List与Set的异同点时都在说: 1.List.Set都实现了Collection接口 2.List是有序的,可以存储重复的元素,允许存入null 3.Set是无序的,不允许存储重 ...