欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解node child_process模塊學習筆記

 更新時間:2018年01月24日 11:06:42   作者:不能說的秘密go  
這篇文章主要介紹了詳解node child_process模塊學習筆記,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

NodeJs是一個單進程的語言,不能像Java那樣可以創(chuàng)建多線程來并發(fā)執(zhí)行。當然在大部分情況下,NodeJs是不需要并發(fā)執(zhí)行的,因為它是事件驅動性永不阻塞。但單進程也有個問題就是不能充分利用CPU的多核機制,根據(jù)前人的經(jīng)驗,可以通過創(chuàng)建多個進程來充分利用CPU多核,并且Node通過了child_process模塊來創(chuàng)建完成多進程的操作。

child_process模塊給予node任意創(chuàng)建子進程的能力,node官方文檔對于child_proces模塊給出了四種方法,映射到操作系統(tǒng)其實都是創(chuàng)建子進程。但對于開發(fā)者而已,這幾種方法的api有點不同

child_process.exec(command[, options][, callback]) 啟動子進程來執(zhí)行shell命令,可以通過回調參數(shù)來獲取腳本shell執(zhí)行結果

child_process.execfile(file[, args][, options][, callback]) 與exec類型不同的是,它執(zhí)行的不是shell命令而是一個可執(zhí)行文件

child_process.spawn(command[, args][, options])僅僅執(zhí)行一個shell命令,不需要獲取執(zhí)行結果

child_process.fork(modulePath[, args][, options])可以用node執(zhí)行的.js文件,也不需要獲取執(zhí)行結果。fork出來的子進程一定是node進程

exec()與execfile()在創(chuàng)建的時候可以指定timeout屬性設置超時時間,一旦超時會被殺死

如果使用execfile()執(zhí)行可執(zhí)行文件,那么頭部一定是#!/usr/bin/env node

進程間通信

node 與 子進程之間的通信是使用IPC管道機制完成。如果子進程也是node進程(使用fork),則可以使用監(jiān)聽message事件和使用send()來通信。

main.js

var cp = require('child_process');
//只有使用fork才可以使用message事件和send()方法
var n = cp.fork('./child.js');
n.on('message',function(m){
 console.log(m);
})

n.send({"message":"hello"});

child.js

var cp = require('child_process');
process.on('message',function(m){
 console.log(m);
})
process.send({"message":"hello I am child"})

父子進程之間會創(chuàng)建IPC通道,message事件和send()便利用IPC通道通信.

句柄傳遞

學會如何創(chuàng)建子進程后,我們創(chuàng)建一個HTTP服務并啟動多個進程來共同做到充分利用CPU多核。

worker.js

var http = require('http');
http.createServer(function(req,res){
 res.end('Hello,World');
 //監(jiān)聽隨機端口
}).listen(Math.round((1+Math.random())*1000),'127.0.0.1');

main.js

var fork = require('child_process').fork;
var cpus = require('os').cpus();
for(var i=0;i<cpus.length;i++){
 fork('./worker.js');
}

上述代碼會根據(jù)你的cpu核數(shù)來創(chuàng)建對應數(shù)量的fork進程,每個進程監(jiān)聽一個隨機端口來提供HTTP服務。

上述就完成了一個典型的Master-Worker主從復制模式。在分布式應用中用于并行處理業(yè)務,具備良好的收縮性和穩(wěn)定性。這里需要注意,fork一個進程代價是昂貴的,node單進程事件驅動具有很好的性能。此例的多個fork進程是為了充分利用CPU的核,并非解決并發(fā)問題.

上述示例有個不太好的地方就是占有了太多端口,那么能不能對于多個子進程全部使用同一個端口從而對外提供http服務也只是使用這一個端口。嘗試將上述的端口隨機數(shù)改為8080,啟動會發(fā)現(xiàn)拋出如下異常。

events.js:72
  throw er;//Unhandled 'error' event
Error:listen EADDRINUSE
XXXX

拋出端口被占有的異常,這意味著只有一個worker.js才能監(jiān)聽8080端口,而其余的會拋出異常。

如果要解決對外提供一個端口的問題,可以參考nginx反向代理的做法。對于Master進程使用80端口對外提供服務,而對于fork的進程則使用隨機端口,Master進程接受到請求就將其轉發(fā)到fork進程中

對于剛剛所說的代理模式,由于進程每收到一個連接會使用掉一個文件描述符,因此代理模式中客戶端連接到代理進程,代理進程再去連接fork進程會使用掉兩個文件描述符,OS中文件描述符是有限的,為了解決這個問題,node引入進程間發(fā)送句柄的功能。

在node的IPC進程通訊API中,send(message,[sendHandle])的第二個參數(shù)就是句柄。

句柄就是一種標識資源的引用,它的內部包含了指向對象的文件描述符。句柄可以用來描述一個socket對象,一個UDP套接子,一個管道主進程向工作進程發(fā)送句柄意味著當主進程接收到客戶端的socket請求后則直接將這個socket發(fā)送給工作進程,而不需要再與工作進程建立socket連接,則文件描述符的浪費即可解決。我們來看示例代碼:

main.js

var cp = require('child_process');
var child = cp.fork('./child.js');
var server = require('net').createServer();
//監(jiān)聽客戶端的連接
server.on('connection',function(socket){
 socket.end('handled by parent');
});
//啟動監(jiān)聽8080端口
server.listen(8080,function(){
//給子進程發(fā)送TCP服務器(句柄)
 child.send('server',server);
});

child.js

process.on('message',function(m,server){
 if(m==='server'){
 server.on('connection',function(socket){
  socket.end('handle by child');
 });
 }
});

使用telnet或curl都可以測試:

wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
handled by parent
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
handle by child
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
handled by parent
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
handled by parent
 

測試結果是每次對于客戶端的連接,有可能父進程處理也有可能被子進程處理?,F(xiàn)在我們嘗試僅提供http服務,并且為了讓父進程更加輕量,僅讓父進程傳遞句柄給子進程而不做請求處理:

main.js

var cp = require('child_process');
var child1 = cp.fork('./child.js');
var child2 = cp.fork('./child.js');
var child3 = cp.fork('./child.js');
var child4 = cp.fork('./child.js');
var server = require('net').createServer();
//父進程將接收到的請求分發(fā)給子進程
server.listen(8080,function(){
 child1.send('server',server);
 child2.send('server',server);
 child3.send('server',server);
 child4.send('server',server);
 //發(fā)送完句柄后關閉監(jiān)聽
 server.close();
});

child.js

var http = require('http');
var serverInChild = http.createServer(function(req,res){
 res.end('I am child.Id:'+process.pid);
});
//子進程收到父進程傳遞的句柄(即客戶端與服務器的socket連接對象)
process.on('message',function(m,serverInParent){
 if(m==='server'){
 //處理與客戶端的連接
 serverInParent.on('connection',function(socket){
  //交給http服務來處理
  serverInChild.emit('connection',socket);
 });
 }
});

當運行上述代碼,此時查看8080端口占有會有如下結果:

 wang@wang ~/code/nodeStudy $ lsof -i:8080
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    5120 wang   11u  IPv6  44561      0t0  TCP *:http-alt (LISTEN)
node    5126 wang   11u  IPv6  44561      0t0  TCP *:http-alt (LISTEN)
node    5127 wang   11u  IPv6  44561      0t0  TCP *:http-alt (LISTEN)
node    5133 wang   11u  IPv6  44561      0t0  TCP *:http-alt (LISTEN)

運行curl查看結果:

wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5127
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5133
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5120
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5126
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5133
wang@wang ~/code/nodeStudy $ curl 192.168.10.104:8080
I am child.Id:5126

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Node Mongoose用法詳解【Mongoose使用、Schema、對象、model文檔等】

    Node Mongoose用法詳解【Mongoose使用、Schema、對象、model文檔等】

    這篇文章主要介紹了Node Mongoose用法,結合實例形式分析了Mongoose使用、Schema、對象、model文檔等基本原理、用法及操作注意事項,需要的朋友可以參考下
    2020-05-05
  • 探索node之事件循環(huán)的實現(xiàn)

    探索node之事件循環(huán)的實現(xiàn)

    這篇文章主要介紹了探索node之事件循環(huán)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • nodejs根據(jù)ip數(shù)組在百度地圖中進行定位

    nodejs根據(jù)ip數(shù)組在百度地圖中進行定位

    本文主要介紹了nodejs根據(jù)ip數(shù)組在百度地圖中進行定位的方法,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • node.js操作mongodb簡單示例分享

    node.js操作mongodb簡單示例分享

    MongoDB是基于Javascript語言的數(shù)據(jù)庫,存儲格式是JSON,而Node也是基于JavaScript的環(huán)境(庫),所以node和mongoDB的搭配能減少因為數(shù)據(jù)轉換帶來的時間空間開銷。今天我們來看看如何通過node.js來操作MongoliaDB
    2017-05-05
  • Node.js檢測端口(port)是否被占用的簡單示例

    Node.js檢測端口(port)是否被占用的簡單示例

    大家有沒有遇到過在開啟本地服務時,有這么一種情況:當前端口已經(jīng)被另一個項目使用了,導致服務開啟失敗。那么接下來,我們通過簡簡單單的示例代碼來檢測端口是否已經(jīng)被占用。有需要的朋友們可以參考借鑒。
    2016-09-09
  • 修改node.js默認的npm安裝目錄實例

    修改node.js默認的npm安裝目錄實例

    今天小編就為大家分享一篇修改node.js默認的npm安裝目錄實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • NodeJs之word文件生成與解析的實現(xiàn)代碼

    NodeJs之word文件生成與解析的實現(xiàn)代碼

    這篇文章主要介紹了NodeJs之word文件生成與解析的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Nodejs Post請求報socket hang up錯誤的解決辦法

    Nodejs Post請求報socket hang up錯誤的解決辦法

    這篇文章主要介紹了Nodejs Post請求報socket hang up錯誤的解決辦法,本文因少加了headers字段信息導致出現(xiàn)這個錯誤,本文給出了一個完整的實現(xiàn)代碼,需要的朋友可以參考下
    2014-09-09
  • 淺談Koa服務限流方法實踐

    淺談Koa服務限流方法實踐

    本篇文章主要介紹了淺談Koa服務限流方法實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • NodeJS 創(chuàng)建目錄和文件的方法實例分析

    NodeJS 創(chuàng)建目錄和文件的方法實例分析

    這篇文章主要介紹了NodeJS 創(chuàng)建目錄和文件的方法,涉及node.js中fs模塊mkdir、writeFile及目錄判斷existsSync等方法的功能與相關使用技巧,需要的朋友可以參考下
    2023-04-04

最新評論