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进程相关,实不相瞒,想要一个赞~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容