返回顶部
首页 > 资讯 > 前端开发 > node.js >详解node中创建服务进程
  • 142
分享到

详解node中创建服务进程

详解进程node 2022-06-04 17:06:29 142人浏览 泡泡鱼
摘要

背景 在node工程部署中,常常涉及到三方:本地客户端、跳板机和服务器(集群)。在通过git触发gitlab hook脚本后,需要在跳板机中执行相应的ssh命令执行shell文件启动node服务器,这需要使

背景

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命令则让子进程有了新的特性:

子进程脱离父进程所在的session控制,两者独立存在互不影响 子进程脱离父进程所在的进程组 子进程脱离原先的命令行终端,终端退出不影响子进程

下面再回顾方法一与方法二的区别,发现方法一其实并不是真正的daemon进程,只是通过侦听相关中断信号并设置nop函数(不执行默认的中断行为)保证子进程继续运行而已;而方法二则是标准的deamon进程创建方式,优先使用!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: 详解node中创建服务进程

本文链接: https://lsjlt.com/news/12641.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解node中创建服务进程
    背景 在node工程部署中,常常涉及到三方:本地客户端、跳板机和服务器(集群)。在通过git触发gitlab hook脚本后,需要在跳板机中执行相应的ssh命令执行shell文件启动node服务器,这需要使...
    99+
    2022-06-04
    详解 进程 node
  • Node.js中创建和管理外部进程详解
    Node被设计用来高效的处理I/O操作,但是你应该知道,有些类型的程序并不适合这种模式。比如,如果你打算用Node处理一个CPU密集的任务,你可能会堵塞事件循环,并因此降低了程序的响应。替代办法是,把CPU...
    99+
    2022-06-04
    建和 详解 进程
  • Node搭建https服务器实例详解
     本文旨在分享搭建https服务器的过程,具体知识点以及相关概念请自行查询。 第一步:创建文件目录如下,在index中引用外部的script.js文件,server.js是...
    99+
    2023-05-18
    Node 搭建 https 服务器
  • 使用 Koa + TS + ESLlint 搭建node服务器的过程详解
    目录初始化项目环境准备安装环境初始化 tsconfig.json简单搭建 Koa 服务器完整项目搭建依赖安装构建目录结构修改 package.json代码规范eslintpretti...
    99+
    2024-04-02
  • 详解_beginthreadex()创建线程
    目录一、使用_beginthreadex()             二、_beginthreadex()与代C...
    99+
    2024-04-02
  • node项目中如何使用Node Schedule创建定时任务
    这篇文章主要介绍了node项目中如何使用Node Schedule创建定时任务,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。nodejs的后...
    99+
    2024-04-02
  • node进程管理工具PM2用法详解
    PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。 安装 npm install -g pm2 常用命...
    99+
    2024-04-02
  • 深入了解Node的多进程服务实现
    目录1. child_process 模块2. spawn3. fork4. exec 和 execFile5. 各方法之间的比较5.1 spawn 和 execFile5.2 ex...
    99+
    2024-04-02
  • node+js搭建时间服务器的思路详解
    目录时间服务器1.思路准备1.1思路来源1.2思路前提要求1.3技术要求2.实现2.1实现准备2.2搭建前台页面2.3搭建后台服务器2.3.1搭建后台2.3.2后台处理要发送的数据2...
    99+
    2024-04-02
  • JavaEE的进程,线程和创建线程的5种方式详解
    目录一、认识进程、线程 1.1什么是进程进程的调度并发式执行1.2认识线程1.3进程、线程之前的区别和联系(面试题)创建线程的几种方式总结一、认识进程、线程  1...
    99+
    2024-04-02
  • C++进程的创建和进程ID标识详细介绍
    目录进程的ID进程创建进程的ID 进程的ID,可称为PID。它是进程的唯一标识,类似于我们的身份证号是唯一标识,因为名字可能会和其他人相同,生日可能会与其他人相同…&h...
    99+
    2024-04-02
  • 创建简单的node服务器实例(分享)
    话不多说直接上代码: var http = require('http') //对URL 解析为对象 //1.导入模块 URl模块 var url = require('url') var fs ...
    99+
    2022-06-04
    实例 简单 服务器
  • Android中创建子线程的方式详解
    在 Android 中,创建子线程的方式通常有以下几种: 使用 Thread 类进行创建 Thread 是 Java 中的一个类,可以通过继承 Thread 类或者创建 Thread...
    99+
    2023-05-18
    Android创建子线程方式 Android创建子线程 Android子线程
  • 阿里云服务器搭建Node环境详细教程
    阿里云服务器是阿里云提供的高性能、可扩展的云计算产品,可以帮助企业快速搭建和扩展应用程序,节省IT运维成本。本教程将详细介绍如何在阿里云服务器上搭建Node环境,以满足开发需求。 步骤一:创建阿里云服务器首先,你需要在阿里云平台上创建一个...
    99+
    2023-11-02
    阿里 环境 服务器
  • oracle创建用户过程详解
    1.首先用管理员用户登陆sqlplus: sqlplus "sysman/安装时设置的密码" 2.创建用户 create user userName identifi...
    99+
    2024-04-02
  • 详解在Java中如何创建多线程程序
    创建多线程程序的第一种方式:创建Thread类的子类 java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类 实现步骤: 1.创建一个T...
    99+
    2024-04-02
  • Python中的多进程怎么创建
    这篇“Python中的多进程怎么创建”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中的多进程怎么创建”文章吧。1...
    99+
    2023-07-02
  • linux中怎么创建守护进程
    这期内容当中小编将会给大家带来有关linux中怎么创建守护进程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。创建子进程,父进程退出   这是编写守护进程的第一步。由于守护进程是脱离控制终端的,因此,完成第...
    99+
    2023-06-09
  • C++中怎么创建新的进程
    在C++中创建新的进程有多种方法,以下是其中一种主要方法: 使用fork()和exec()函数: #include <io...
    99+
    2024-04-02
  • 云服务器部署Node项目:创建文件夹
    1. 登录到云服务器 首先,你需要登录到你的云服务器。你可以使用SSH客户端,如PuTTY(Windows)或Terminal(Mac/Linux),通过输入服务器的IP地址和凭据来登录。 2. 安装Node.js 在部署Node项目之前...
    99+
    2023-10-28
    文件夹 服务器 项目
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作