当我们写cpu计算密集型代码的时候
首先tab1访问/sum卡住, tab2访问/也会卡住。
http.createServer((req,res)=>{
if(req.url === '/sum'){
var total = 0;
for(var i =0;i<1000000;i++) {
total = i++;
}
res.end('total:'+total);
}else{
res.end('end ok');
}
}).listen(3000);
改进 spawn 产卵
http.createServer((req,res)=>{
if(req.url === '/sum'){
let cp = spawn('node',['sum.js'],{ // 我如果有很大输出需要处理 spawn 'pipe'
cwd:path.resolve(__dirname,'test'),
stdio:[0,1,2,'ipc']
});
cp.on('message',function(total){
res.end('total:'+total);
})
}else{
res.end('end ok');
}
}).listen(3000);
// ===================================
var total = 0;
for(var i =0;i<10000000000;i++) {
total = i++;
}
process.send(total+ '');
stdio
stdio 当时inherit 表示[0,1,2] [stdin,stdout,stderr]
stdio 还可以能是 ‘pipe’ [‘pipe’,‘pipe’,‘pipe’]
stdio 如果监听message的,必须走ipc的模式。[0,1,2,ipc]
spawn可以使用pipe ,但是一般使用fork, fork默认就是ipc
fork silent 参数默认false[0,1,2],然后是ture,表示pipe模式. true的时候不会子进程中打印console.log(’’)的内容。无论true还是false都有ipc
父和子通信
cp代表父,process代表子进程。
cp.stdout.on('data',data => console.log(data));
process.stdout.end('ggg'); // process.stdout.write();
=========
cp.send('server',server);
process.on('message', data => {})
cp.kill(); 杀死所有子进程。
process.exit();推出子进程。
断开父子进程之间的关系;
exec execFile
功能就是执行命令 核心也是 基于spawn的 如果数据小于200 可以直接使用execFile
用用shell
execFile('ls',['-ll'],(err,stdout,stderr)=>{
// http-server
console.log(stdout)
})
默认exec 会启动一个shell
exec('ls -ll',(err,stdout,stderr)=>{
// http-server
console.log(stdout)
})
打包后 删除目录 sh xxx.sh
exec('open http://localhost:3000',function(err,stdout) {
console.log(stdout)
});
exec('git status',function (err,stdout) {
console.log(stdout)
});
process 去实现 cluster
// process -> cluster -> pm2
const {fork} = require('child_process');
const cpus = require('os').cpus().length-1;
const http = require('http');
// 我希望 开启多个进程 监听同一个服务
fork 不是开的越多越好 数量 和cpu数相同
一个服务 可以启动在不同的cpu 上 必须监听同一个端口
let server = http.createServer((req,res)=>{
res.end('parent:'+process.pid);
}).listen(3000);
console.log(process.pid)
for(let i = 0 ; i < cpus;i++){
let child = fork('server.js');
// server 的名字固定 就是传入一个http服务
child.send('server',server);
}
// 上线的时候 需要开启多个进程, 给你提供一个cluster模块
node 实现了一个cluster
// 族
const cluster = require('cluster');
const cpus = require('os').cpus().length;
const http = require('http');
cluster帮你提供了fork方法
主干
在集群的模式下 可以 监听同一个端口号
守护进程
if(cluster.isMaster){
console.log('主');// 可以开启子进程,如果fork后会讲此文件重新执行
// 保证项目的健壮性,一个挂了 可以重启
cluster.on('exit',function (worker) {
console.log(worker.process.pid);
cluster.fork();
})
for(let i = 0; i< cpus;i++){
cluster.fork(); // 进程的用法
}
}else{
// 负载均衡
http.createServer((req,res)=>{
if(Math.random()>0.5){
aa();
}
res.end('process'+process.pid)
}).listen(3000);
console.log(process.pid);
}
pm2
生成一个ecosystem.config.js
pm2 ecosystem