背景

在node工程部署中,常常涉及到三方:本地客户端、跳板机和服务器(集群)。在通过git触发gitlab hook脚本后,需要在跳板机中执行相应的ssh命令执行shell文件启动node服务器,这需要使用一个常用的命令setsid,这样当ssh命令执行完毕shell退出后,node服务器仍正常运行,此时node服务进程就是一个最典型的daemon进程(后台服务进程)。
那么,在node项目中,如何创建一个daemon进程呢?最简单的方式,其实就是采用类似上文中介绍的方式:
复制代码 代码如下:
require('child_process').exec('setsid node app.js >/dev/null 2>&1 &');
这样可以通过执行shell的方式实现daemon进程。不过本文的重点并不是介绍这种“命令行”的方式实现daemon进程,而且本文会详细讲述daemon进程的创建原理,且看下文。
目标
在当前业务中,之所以需要创建daemon进程就是为了保证中断创建该进程的父进程(ctrl+c)或者父进程执行完毕后并不影响daemon进程的执行。下文介绍两种实现方式,实现原理细节上有些出入。
下文中的所有讨论都是在linux环境下进行。
实现一
在linux系统中,父进程创建出子进程,此时父进程若退出,此时子进程则变为孤儿进程,其ppid变为1,即成为init进程的子进程。在node环境下,如果不针对子进程的stdio做一些特殊处理父进程其实不会真正退出,而是直到子进程执行完毕后再退出。之所以出现这种情况是由于node创建子进程时默认会通过pipe方式将子进程的输出导流到父进程的stream中(childProcess.stdout、childProcess.stderr),提供在父进程中输出子进程消息的能力。
因此,解决此种问题可给子进程的stdio重新赋值:
file: parent.js
let cp = require('child_process');
const sp = cp.spawn('node',['./c.js'],{
stdio: [process.stdin,process.stdout,process.stderr]
});
setTimeout(()=>{console.log('parent out')},5000);
--------------
file: c.js
setTimeout(()=>{
console.log('children exit');
},10000)
通过在parent.js中设置子进程的stdio为当前终端(其实继承了父进程的stdio),这样父进程在5s后退出,此时子进程的ppid变为1,10s后子进程退出。
上述实现只满足“父进程正常退出,子进程成为守护进程”的情况,一旦通过“ctrl+c”的方式终端父进程,子进程仍会退出,这还是与node底层实现有关。默认“ctrl+c”触发SIGINT信号,父进程接受信号后发送给子进程,如果子进程存在SIGINT侦听函数,则会执行该函数,否则执行exit系统调用子进程退出。因此,如果要让子进程在接收到SIGINT信号不退出,只需要不作处理即可:
file: c.js
process.on('SIGINT',function(){
console.log('child sigint');
});
setTimeout(()=>{
console.log('children exit');
},10000)
以上实现,可以满足我们最初指定的目标:“父进程退出或者中断,子进程仍正常运行”。
实现二
node官方提供了创建daemon进程的相关API,如果不仔细阅读文档还真不容易发现该特性。在child_process模块中有个spawn函数,通过spawn可以执行shell命令及其相关选项,同时spawn提供了创建子进程的一些选项,其中“detached”选项则与我们的需求密切相关。
detached选项可以让node原生帮我们创建一个daemon进程,设置datached为true可以创建一个新的session和进程组,子进程的pid为新创建进程组的组pid,这与setsid起到相同的作用。此时的子进程已经和其父进程属于两个session,因此父进程的退出和中断信号不会传递给子进程,子进程不会接受到父进程的中断信号自然也不会退出。当父进程结束之后,子进程变为孤儿进程从而被init进程接收,ppid设置为1。
file: parent.js
let cp = require('child_process');
const sp = cp.spawn('node',['./c.js'],{
detached: true,
stdio: [process.stdin,process.stdout,process.stdout]
});
sp.unref();
setTimeout(()=>{console.log('parent out')},5000);
----------------------
file: c.js
setTimeout(()=>{
console.log('children exit');
},100000)
此时,c.js文件并未设置SIGINT事件侦听函数,在父进程中断后仍会正常运行,正是由于其和父进程分属于两个session。
在parent.js文件中设置了sp.unref()函数,目的是“避免父进程等待子进程退出”。那么为何会出现上述情况呢?这与node的事件循环有关,让父进程的事件循环排除对ChildProcess子进程对象的引用,可以使父进程单独退出。
总结
为什么上文介绍的两个方法都可以实现daemon进程呢?这还得回到系统层面进行分析。在linux系统创建一个daemon进程需要几个步骤:
1.父进程创建子进程,父进程退出,让子进程成为孤儿进程,ppid=1
2.通过setsid命令或函数在子进程中创建新的会话和进程组
3.设置当前目录
4.设置文件权限,并关闭父进程继承打开的fd
所谓会话和进程组,则是在linux多任务多用户下的概念。不同会话的进程无法通过通信,因此父子进程相隔离。而执行setsid命令则让子进程有了新的特性:
下面再回顾方法一与方法二的区别,发现方法一其实并不是真正的daemon进程,只是通过侦听相关中断信号并设置nop函数(不执行默认的中断行为)保证子进程继续运行而已;而方法二则是标准的deamon进程创建方式,优先使用!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# nodejs
# 创建进程
# 进程
# node
# 服务进程
# 详解nodejs中的process进程
# nodejs中向HTTP响应传送进程的输出
# Nodejs中解决cluster模块的多进程如何共享数据问题
# Nodejs极简入门教程(三):进程
# Nodejs进程管理模块forever详解
# 利用NodeJS的子进程(child_process)调用系统命令的方法分享
# 创建一个
# 正常运行
# 这还
# 这与
# 命令行
# 仍会
# 是在
# 有个
# 完毕后
# 则是
# 两种
# 可以通过
# 发现该
# 真不
# 这种情况
# 要让
# 只需要
# 可以实现
# 涉及到
# 不作
相关文章:
高端智能建站公司优选:品牌定制与SEO优化一站式服务
建站之星2.7模板快速切换与批量管理功能操作指南
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
江苏网站制作公司有哪些,江苏书法考级官方网站?
公司网站设计制作厂家,怎么创建自己的一个网站?
建站之星备案流程有哪些注意事项?
网站制作价目表怎么做,珍爱网婚介费用多少?
香港服务器WordPress建站指南:SEO优化与高效部署策略
外贸公司网站制作哪家好,maersk船公司官网?
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
网站网页制作专业公司,怎样制作自己的网页?
网站制作的步骤包括,正确网址格式怎么写?
建站之星导航配置指南:自助建站与SEO优化全解析
盘锦网站制作公司,盘锦大洼有多少5G网站?
在线流程图制作网站手机版,谁能推荐几个好的CG原画资源网站么?
北京的网站制作公司有哪些,哪个视频网站最好?
学校免费自助建站系统:智能生成+拖拽设计+多端适配
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
中山网站制作网页,中山新生登记系统登记流程?
建站之星如何保障用户数据免受黑客入侵?
建站之星安装后如何自定义网站颜色与字体?
建站主机空间推荐 高性价比配置与快速部署方案解析
如何将凡科建站内容保存为本地文件?
如何确保FTP站点访问权限与数据传输安全?
建站主机选购指南:核心配置与性价比推荐解析
网站制作报价单模板图片,小松挖机官方网站报价?
专业公司网站制作公司,用什么语言做企业网站比较好?
湖北网站制作公司有哪些,湖北清能集团官网?
Android使用GridView实现日历的简单功能
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
韩国服务器如何优化跨境访问实现高效连接?
网站制作说明怎么写,简述网页设计的流程并说明原因?
Swift开发中switch语句值绑定模式
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
如何快速查询域名建站关键信息?
天津个人网站制作公司,天津网约车驾驶员从业资格证官网?
如何通过cPanel快速搭建网站?
C++中引用和指针有什么区别?(代码说明)
交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?
孙琪峥织梦建站教程如何优化数据库安全?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
定制建站策划方案_专业建站与网站建设方案一站式指南
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
如何通过VPS建站实现广告与增值服务盈利?
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
如何通过NAT技术实现内网高效建站?
如何获取PHP WAP自助建站系统源码?
实例解析angularjs的filter过滤器
如何在西部数码注册域名并快速搭建网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。