node提供了四種方法來建立子進程,分別是child_process.exec(),child_process.execFile(),
child_process.fork(),child_process.spawn()。他們都返回子進程對象。
exec:啓動一個子進程執行命令,而且有一個回調函數獲知子進程的情況。而且能夠設置超時時間。
execFile:啓動一個子進程文件,注意這裏的文件不必定是js文件,node能夠執行的文件,例如window下的
bat文件,等而且也有一個回調,而且能夠設置超時時間。
spawn:只是簡單的執行一個子進程命令。不能設置超時時間。
fork:執行一個文件,不能設置超時和回調。node
node進程間通訊,指父進程和子進程之間的通訊,子進程之間是不能夠通訊的,有點想react的組件。經過send和message事件進行通訊。react
//parent.js服務器
let cp = require('child_process');
let n = cp.fork('./p_sub.js');
let time = new Date();
console.log('current time:'+ time);
n.on('message',function(msg){
console.log(`time have passd ${new Date() - time}`);
console.log('parent get message:' + msg.foo);
})
n.send({hello:'world'});
console.log('send ok');
while((new Date()) - time < 20){
// do nothing...
}負載均衡
//sbu.js異步
let time = new Date();
console.log('current time:'+ time);
process.on('message',function(m){
console.log('massage from parent:' + m.hello);
process.send({foo:'bar'});
})socket
父子進程間通訊如此簡單。接下來就要談論關鍵的東西了,node的多進程服務器。在這以前,咱們還須要瞭解的一個東西叫作句柄,句柄能夠理解問表示資源的引用,總感受像是指針這樣的東西,能夠理解爲js對象名和對象之間的關係,不過這是系統對資源的引用,句柄能夠是一個socket對象,套接字,管道等。父進程和子進程之間能夠傳遞句柄。這就是弄的多進程服務器的關鍵,主進程接受80端口(固然也能夠其餘端口)請求,而後將句柄 傳遞個子進程,由子進程處理,而後將結果發送給主進程。豈不是很好。異步I/O單線程,又充分利用cpu資源。若是這樣理解那你就錯了。其實node發送的句柄,並非真正的對象,而是這個對象的引用,這是一個搶佔是服務至關於多個進程同時監聽了同一個端口。tcp
//process.js函數
let sub_process = require('child_process');
let child1 = sub_process.fork('./p_children.js');
let child2 = sub_process.fork('./p_children.js');
let child3 = sub_process.fork('./p_children.js');ui
let server = require('net').createServer();
server.listen(1337,function(){
child1.send('server',server);
child2.send('server',server);
child3.send('server',server);
server.close();
})spa
//p_children.js
let http = require('http');
let server = http.createServer(function(req,res){
res.writeHead(200,{'Conten-Type':'text-plain'});
res.end('handle by child,pis is ' + process.pid);
});
process.on('message',(m,tcp)=>{
if(m==='server'){
tcp.on('connection',function(socket){
server.emit('connection',socket);
})
}
})
這只是萬里長征的第一步,單線程總歸是不穩定的,例如檢測到子進程推出後重啓另外一個進程,而且限制子進程數量,子進程之間要作負載均衡,又忽然感受一臉矇蔽,爲應對這些node引入了cluster模塊,解決多cpu利用率問題,上面提到的這些問題用cluster模塊輕鬆搞定。
var cluster = require('cluster');
cluster.setupMaster({
exec:'p_children.js'
})
let cpus = require('os').cpus();
for(let i=0;i<cpus.length;i++){
cluster.fork();
}
這樣以來就感受爽歪歪了,不過淡定,如今用pm2直接配置就能夠作這個事情,因此上面你看的沒用,直接用pm2就對了。因此上面說的基本是扯淡。