最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解node中創(chuàng)建服務(wù)進(jìn)程

 更新時間:2017年05月09日 08:27:06   作者:royalrover  
本篇文章主要介紹了詳解node中創(chuàng)建服務(wù)進(jìn)程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

背景

在node工程部署中,常常涉及到三方:本地客戶端、跳板機(jī)和服務(wù)器(集群)。在通過git觸發(fā)gitlab hook腳本后,需要在跳板機(jī)中執(zhí)行相應(yīng)的ssh命令執(zhí)行shell文件啟動node服務(wù)器,這需要使用一個常用的命令setsid,這樣當(dāng)ssh命令執(zhí)行完畢shell退出后,node服務(wù)器仍正常運行,此時node服務(wù)進(jìn)程就是一個最典型的daemon進(jìn)程(后臺服務(wù)進(jìn)程)。

那么,在node項目中,如何創(chuàng)建一個daemon進(jìn)程呢?最簡單的方式,其實就是采用類似上文中介紹的方式:

復(fù)制代碼 代碼如下:

require('child_process').exec('setsid node app.js >/dev/null 2>&1 &');

這樣可以通過執(zhí)行shell的方式實現(xiàn)daemon進(jìn)程。不過本文的重點并不是介紹這種“命令行”的方式實現(xiàn)daemon進(jìn)程,而且本文會詳細(xì)講述daemon進(jìn)程的創(chuàng)建原理,且看下文。

目標(biāo)

在當(dāng)前業(yè)務(wù)中,之所以需要創(chuàng)建daemon進(jìn)程就是為了保證中斷創(chuàng)建該進(jìn)程的父進(jìn)程(ctrl+c)或者父進(jìn)程執(zhí)行完畢后并不影響daemon進(jìn)程的執(zhí)行。下文介紹兩種實現(xiàn)方式,實現(xiàn)原理細(xì)節(jié)上有些出入。

下文中的所有討論都是在linux環(huán)境下進(jìn)行。

實現(xiàn)一

在linux系統(tǒng)中,父進(jìn)程創(chuàng)建出子進(jìn)程,此時父進(jìn)程若退出,此時子進(jìn)程則變?yōu)楣聝哼M(jìn)程,其ppid變?yōu)?,即成為init進(jìn)程的子進(jìn)程。在node環(huán)境下,如果不針對子進(jìn)程的stdio做一些特殊處理父進(jìn)程其實不會真正退出,而是直到子進(jìn)程執(zhí)行完畢后再退出。之所以出現(xiàn)這種情況是由于node創(chuàng)建子進(jìn)程時默認(rèn)會通過pipe方式將子進(jìn)程的輸出導(dǎo)流到父進(jìn)程的stream中(childProcess.stdout、childProcess.stderr),提供在父進(jìn)程中輸出子進(jìn)程消息的能力。

因此,解決此種問題可給子進(jìn)程的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中設(shè)置子進(jìn)程的stdio為當(dāng)前終端(其實繼承了父進(jìn)程的stdio),這樣父進(jìn)程在5s后退出,此時子進(jìn)程的ppid變?yōu)?,10s后子進(jìn)程退出。

上述實現(xiàn)只滿足“父進(jìn)程正常退出,子進(jìn)程成為守護(hù)進(jìn)程”的情況,一旦通過“ctrl+c”的方式終端父進(jìn)程,子進(jìn)程仍會退出,這還是與node底層實現(xiàn)有關(guān)。默認(rèn)“ctrl+c”觸發(fā)SIGINT信號,父進(jìn)程接受信號后發(fā)送給子進(jìn)程,如果子進(jìn)程存在SIGINT偵聽函數(shù),則會執(zhí)行該函數(shù),否則執(zhí)行exit系統(tǒng)調(diào)用子進(jìn)程退出。因此,如果要讓子進(jìn)程在接收到SIGINT信號不退出,只需要不作處理即可:

file: c.js

process.on('SIGINT',function(){
  console.log('child sigint');
});

setTimeout(()=>{
  console.log('children exit');
},10000)

以上實現(xiàn),可以滿足我們最初指定的目標(biāo):“父進(jìn)程退出或者中斷,子進(jìn)程仍正常運行”。

 實現(xiàn)二

node官方提供了創(chuàng)建daemon進(jìn)程的相關(guān)API,如果不仔細(xì)閱讀文檔還真不容易發(fā)現(xiàn)該特性。在child_process模塊中有個spawn函數(shù),通過spawn可以執(zhí)行shell命令及其相關(guān)選項,同時spawn提供了創(chuàng)建子進(jìn)程的一些選項,其中“detached”選項則與我們的需求密切相關(guān)。

detached選項可以讓node原生幫我們創(chuàng)建一個daemon進(jìn)程,設(shè)置datached為true可以創(chuàng)建一個新的session和進(jìn)程組,子進(jìn)程的pid為新創(chuàng)建進(jìn)程組的組pid,這與setsid起到相同的作用。此時的子進(jìn)程已經(jīng)和其父進(jìn)程屬于兩個session,因此父進(jìn)程的退出和中斷信號不會傳遞給子進(jìn)程,子進(jìn)程不會接受到父進(jìn)程的中斷信號自然也不會退出。當(dāng)父進(jìn)程結(jié)束之后,子進(jìn)程變?yōu)楣聝哼M(jìn)程從而被init進(jìn)程接收,ppid設(shè)置為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文件并未設(shè)置SIGINT事件偵聽函數(shù),在父進(jìn)程中斷后仍會正常運行,正是由于其和父進(jìn)程分屬于兩個session。

在parent.js文件中設(shè)置了sp.unref()函數(shù),目的是“避免父進(jìn)程等待子進(jìn)程退出”。那么為何會出現(xiàn)上述情況呢?這與node的事件循環(huán)有關(guān),讓父進(jìn)程的事件循環(huán)排除對ChildProcess子進(jìn)程對象的引用,可以使父進(jìn)程單獨退出。

總結(jié)

為什么上文介紹的兩個方法都可以實現(xiàn)daemon進(jìn)程呢?這還得回到系統(tǒng)層面進(jìn)行分析。在linux系統(tǒng)創(chuàng)建一個daemon進(jìn)程需要幾個步驟:

1.父進(jìn)程創(chuàng)建子進(jìn)程,父進(jìn)程退出,讓子進(jìn)程成為孤兒進(jìn)程,ppid=1

2.通過setsid命令或函數(shù)在子進(jìn)程中創(chuàng)建新的會話和進(jìn)程組

3.設(shè)置當(dāng)前目錄

4.設(shè)置文件權(quán)限,并關(guān)閉父進(jìn)程繼承打開的fd

所謂會話和進(jìn)程組,則是在linux多任務(wù)多用戶下的概念。不同會話的進(jìn)程無法通過通信,因此父子進(jìn)程相隔離。而執(zhí)行setsid命令則讓子進(jìn)程有了新的特性:

  1. 子進(jìn)程脫離父進(jìn)程所在的session控制,兩者獨立存在互不影響
  2. 子進(jìn)程脫離父進(jìn)程所在的進(jìn)程組
  3. 子進(jìn)程脫離原先的命令行終端,終端退出不影響子進(jìn)程

下面再回顧方法一與方法二的區(qū)別,發(fā)現(xiàn)方法一其實并不是真正的daemon進(jìn)程,只是通過偵聽相關(guān)中斷信號并設(shè)置nop函數(shù)(不執(zhí)行默認(rèn)的中斷行為)保證子進(jìn)程繼續(xù)運行而已;而方法二則是標(biāo)準(zhǔn)的deamon進(jìn)程創(chuàng)建方式,優(yōu)先使用!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node.js中的fs.link方法使用說明

    node.js中的fs.link方法使用說明

    這篇文章主要介紹了node.js中的fs.link方法使用說明,本文介紹了fs.link的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 利用node.js寫一個爬取知乎妹紙圖的小爬蟲

    利用node.js寫一個爬取知乎妹紙圖的小爬蟲

    這篇文章主要給大家介紹了利用node.js寫一個爬取知乎妹紙圖的小爬蟲,文中給出了詳細(xì)的示例代碼和介紹,對大家具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。
    2017-05-05
  • pm2工具在Node.js開發(fā)部署中的重要作用詳解

    pm2工具在Node.js開發(fā)部署中的重要作用詳解

    這篇文章主要為大家介紹了pm2工具在Node.js開發(fā)部署中的重要作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Node.js筆記之process模塊解讀

    Node.js筆記之process模塊解讀

    這篇文章主要介紹了Node.js process模塊解讀,process存在于全局對象上,不需要使用require()加載即可使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Win7系統(tǒng)只能安裝的nodejs13.14,如何安裝高版本nodejs

    Win7系統(tǒng)只能安裝的nodejs13.14,如何安裝高版本nodejs

    正常情況下,Win7支持的Node.js最高版本是V13.14,但在開發(fā)過程中,有不少Vue項目或其他需要依賴Node環(huán)境的項目,對Node版本要求都比較高,對此,我們要么重裝操作系統(tǒng)到Win8以上,要么就得想辦法在Win7中安裝高版本的Node,否則很多項目在編譯打包時可能會出現(xiàn)警告信息或失敗
    2024-11-11
  • nodejs如何解決高并發(fā)問題

    nodejs如何解決高并發(fā)問題

    這篇文章主要介紹了nodejs如何解決高并發(fā)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • nodejs實現(xiàn)獲取某寶商品分類

    nodejs實現(xiàn)獲取某寶商品分類

    這篇文章主要介紹了nodejs實現(xiàn)獲取某寶商品分類,十分的簡單實用,進(jìn)入后臺直接打開控制臺,把代碼粘進(jìn)去運行就OK了,有需要的小伙伴可以參考下。
    2015-05-05
  • 詳解node如何將Excel導(dǎo)入數(shù)據(jù)庫

    詳解node如何將Excel導(dǎo)入數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了node如何通過腳本實現(xiàn)將Excel導(dǎo)入mysql數(shù)據(jù)庫里,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2024-11-11
  • iOS + node.js使用Socket.IO框架進(jìn)行實時通信示例

    iOS + node.js使用Socket.IO框架進(jìn)行實時通信示例

    本篇文章主要介紹了iOS + node.js使用Socket.IO框架進(jìn)行實時通信示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • node項目使用http模塊發(fā)送get-post請求方式

    node項目使用http模塊發(fā)送get-post請求方式

    這篇文章主要介紹了node項目使用http模塊發(fā)送get-post請求方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09

最新評論

宿松县| 普兰店市| 榆社县| 阿勒泰市| 忻城县| 宝山区| 乌兰察布市| 太湖县| 宁远县| 寿光市| 罗平县| 兴海县| 女性| 涿鹿县| 正蓝旗| 江都市| 万安县| 台东市| 浦北县| 盐亭县| 泰兴市| 安福县| 邛崃市| 陵水| 罗田县| 都兰县| 平罗县| 白山市| 商河县| 宿州市| 莱阳市| 洪泽县| 纳雍县| 美姑县| 黄大仙区| 尼玛县| 昭苏县| 汝城县| 南召县| 民乐县| 惠来县|