进程的使用是为了解决服务器cpu的利用和保证程序的健壮性和稳定性。以下代码可以在gitee获取:
地址:https://gitee.com/xifeng-canyang/node-deep/tree/master/playTheProcess
通过child_process我们可以获取进程实例
cp = require('child_process');
其下有四个方法:
- spawn() 启动一个子进程来执行命令
cp.spawn('node',['work.js']) - exec() 启动一个子进程来执行命令,与spawn()不同的是,他有一个回调函数来获知子进程的状况
cp.exec('node work.js',(err,stdout,stderr) => {}) - execFile() 启动一个子进程来执行可执行的文件,如果他运行的是js文件,那么文件首航内容必须添加: #!/usr/bin/env node
cp.execFile('work.js',(err,stdout,stderr) => {}) - fork() 与spawn类似,不同的是,fork只需要执行js文件模块即可
cp.fork('./work.js)
简单使用
创建文件:child-test/parents.js
const cpu = require('child_process');
const parent = cpu.fork(__dirname+'/sub.js');
parent.on('message',(m) => {
console.log('parent get msg',m)
})
parent.send('hello world!!!')
再创建文件:sub.js
process.on('message',(m) => {
console.log('child get msg',m)
})
process.send({ foo: 'bar'} )
当服务器跑起来的时候,各自通过message事件监听到对应的消息。
cluster
集群模块允许轻松创建所有共享服务器端口的子进程。
- 通过isPrimary来区分主子进程
- 通过workers获取所有的子进程;用于子进程,则获取了当前的子进程
- worker.exitedAfterDisconnect,如果是以disconnected()退出,为true;其他方式退出,如kill,则为false;没退出时为undefined
- worker.id 为每个worder的一个标志
- worker.isConnected() worker的链接状态
- worker.isDead() 进程的终止符,可以在exit事件中监听到,默认是false
我们先封装一个主进程的worker,新建文件cluster/common.js
export const handleWork = (worker,index) => {
let timeout;
if ( index === 100 ) {
console.log(`
worker 没退出之前: \n
exitedAfterDisconnect: ${worker.exitedAfterDisconnect}
id: ${worker.id}
isConnected: ${worker.isConnected()}
isDead: ${worker.isDead()}
`);
// 第一个worker发送消息
worker.process.send({ msg: 'hi there'});
}
worker.on('exit',(code,signal) => {
// 当执行work.kill的时候signal = SIGTERM
if (signal) {
console.log(`worker was killed by signal: ${signal}`, worker.exitedAfterDisconnect);
console.log(`
worker 断开链接之后: \n
exitedAfterDisconnect: ${worker.exitedAfterDisconnect}
id: ${worker.id}
isConnected: ${worker.isConnected()}
isDead: ${worker.isDead()}
`)
} else if (code !== 0) {
console.log(`worker exited with error code: ${code}`);
} else {
console.log('worker success!');
}
})
worker.on('error',(err) => {
console.log(err,'work has error')
})
worker.on('disconnect',() => {
console.log(index,'work has disconnected');
clearTimeout(timeout);
})
worker.on('fork', (worker) => {
console.log('worker is dead:', worker.isDead());
});
worker.on('listening', (address) => {
// Worker is listening { addressType: 4, address: null, port: 8000, fd: undefined }
console.log(' Worker is listening',address);
timeout = setTimeout(() => {
// 当触发某种情况时,如index=200,我们就杀死进程
if ( index === 200) {
// worker.kill();
}
}, 2000);
});
// 在主进程中间接收消息,当process.send发送数据过来的时候,这里可以监听到
worker.on('message', (msg) => {
console.log('message: ',msg)
});
worker.on('online', () => {
// Worker is online
console.log('Worker is online')
});
}
再新建文件cluster/index.js
import cluster from 'node:cluster';
import http from 'node:http';
import os from 'node:os';
import { handleWork } from './common.js'
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
const workIds = [];
for ( let i = 1 ; i < 3 ; i ++ ) {
const worker = cluster.fork();
workIds.push(worker.process.pid);
// console.log('signal',worker)
handleWork(worker,i*100)
}
console.log('work ids: ',workIds)
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req,res) => {
res.writeHead(200);
res.end('hello cluster');
// Notify primary about the request
process.send({ cmd: 'notifyRequest' });
process.on('message', (msg) => {
console.log('received child msg: ',msg)
});
console.log(process.pid,'process pid')
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
当服务器跑起来的时候,便可以通过worker的监听事件获取到对应的信息。
以上便是实战node进程相关,实不相瞒,想要一个赞~