这是一篇关于Win下创建守护进程的文章,很入门,为了NAE的邀请码!
前段时间做了一个代理工具,主要功能是将线上assets服务器(单独域名存放css、js或其它文件)指向本地80端口,当请求文件在磁盘上存在则读取,否则用http.get方式获取线上内容。
由于工具运行前需要修改hosts文件,因此想让这一过程自动化。即,代理启动时,自动添加hosts绑定,反之则去除绑定。
最开始,我必须开启两个不同的CMD窗口,来分别启动2个程序,否则,在一个CMD窗口用node进程模块启动的进程,当用户关闭CMD窗口时,子进程也随之退出了。
因此,必须确保守护进程脱离终端控制,这种程序在不同系统中可能会被称为服务、后台进程、僵尸程序,或者守护进程等等。此应用场景中,应该称为后台进程,但为了好理解一点,仍称为守护进程。
守护进程至少有2个特点:
- 尽可能一直运行
- 本身足够健壮
特点1很好理解,这样才能最快的侦测到主进程的运行状态,而特点2则特点1的必然条件。除此之外,还有一个自己添加的特点,让守护进程是隐藏窗口模式运行,这样避免占用任务栏、桌面,也可以防止自己误关闭等。
尽管没有窗口,但并不妨碍我们对守护进程进行操作,例如可以让守护进程开放一个http端口,通过网页来控制自己。当访问 127.0.0.1:5000/kill 时,则触发process.kill(process.pid)。
由于不想用forever等模块,想尽可能简单的实现,所以使用了Win系统中,自带的wscript命令来创建守护进程。
下面是大致的步骤:
创建一个watch.vbs文件,只有一行内容:
CreateObject("WScript.Shell").Run "node watch",0
请注意末尾的0,表示以隐藏模式运行,否则会产生一个CMD窗口。
主程序 main.js:
//your code
//在30002端口侦听,守护进程启动时会发轮询过来
require('net').createServer(function(net) {
//应答请求,返回主进程PID
net.write(process.pid.toString());
net.pipe(net);
}).listen(30002);
//启动守护进程
require('child_process').exec('wscript watch.vbs', {cwd:__dirname});
实际上,上方最后一行代码中,wscript会确保vbs中启动的进程脱离终端控制。
这是本文最关键的一行。
守护进程 watch.js
//代码较占版面,就不贴出来了: //动作:不停的setTimeout去尝试连接30002端口,根据结果,来选择是否去除hosts绑定。
最后,在CMD中node main,会发现任务管理器中有两个node.exe进程,关掉当前的CMD,进程列表中仍有个node.exe驻留着,它即守护进程。
完!
nodeJS初学者,不知大家有没有更好的方案。 目前来说,在Unix或Linux中,还未找到类似于Win这么简单的办法。否则只能尝试判断系统类型,然后选择forever模块了。