node进程实战篇

进程的使用是为了解决服务器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进程相关,实不相瞒,想要一个赞~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容