• Nodejs 如何开启多进程,进程如何通讯


    最重要的一句话刻在心里:JS是单线程的

    进程(process)和线程(thread)的区别

    • 进程,OS 进行资源分配和调度的最小单位,有独立内存空间
    • 线程,OS 进行运算调度的最小单位,共享进程内存空间

    为何需要多进程

    • 多核 CPU,更适合处理多进程
    • 内存较大,多个进程才能更好的利用(单进程有内存上限)

    总之,是为了“压榨”机器资源。

    Nodejs 开启多进程的方式:

    • webWorker 方式开启多进程(此方法在浏览器中也可以使用,我的使用例子就是 webview 中,Custom Dashboard 项目里面,为了和 desktop 进行通讯,会使用 webWorker.postMessage() 方法发送数据给 desktop,使用 window.addEventListener(“message”, () => {}) 来接收 desktop 的数据)
    • fork
    • cluster

    使用 child_process.fork 方式

    const fork = require("child_process").fork;
    
    • 1

    下面 demo 一个创建子进程的例子,该例子先创建一个 server,启动服务之后访问 localhost:3000/get-sum ,页面会打印 sum is 4995500 字符串。

    // process.js 
    const http = require("http");
    const fork = require("child_process").fork;
    
    const server = http.createServer((req, res) => {
        if (req.url === "/get-sum") {
            console.info("主进程 id", process.pid);
    
            // 开启子进程
            const computeProcess = fork("./compute.js");
            computeProcess.send("开始计算");
    
            // 接收子进程的消息
            computeProcess.on("message", data => {
                console.info("主进程接收到的信息:", data);
                res.end("sum is " + data);
            });
    
            // 接收意外情况
            computeProcess.on("close", () => {
                console.info("子进程因报错而退出");
                res.end("error");
            })
        }
    });
    server.listen(3000, () => {
    	console.info("localhost:3000");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    // compute.js
    /**
     * @description 子进程,计算
     */
    
    function getSum() {
        let sum = 0;
        for (let i = 0; i< 10000; i ++) {
            sum += i;
        }
        return sum;
    }
    
    // 接收主进程的消息
    process.on("message", data => {
        console.info("子进程 id", process.pid);
        console.info("子进程接收到的信息:", data);
    
        const sum = getSum();
    
        // 发送消息给主进程
        process.send(sum);
    
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    使用 cluster 方式

    运行 node cluster.js,访问 localhost:3000,页面会打印出 done。

    // cluster.js
    const http = require("http");
    // 根据 cpu 的核数来决定开启进程的数量
    const cpuCoreLength = require("os").cpus().length;
    const cluster = require("cluster");
    
    // 如果是主进程,就开启子进程
    if (cluster.isMaster) {
        for (let i = 0; i < cpuCoreLength; i ++) {
            cluster.fork(); // 开启子进程
        }
    
        cluster.on("exit", worker => {
            console.info("子进程退出");
            cluster.fork(); // 进程守护,再次开启子进程
        });
    } else {
        // 子进程
        // 多个子进程会共享一个 TCP 连接,提供一份网络服务
        const server = http.createServer((req, res) => {
            res.writeHead(200);
            res.end("done");
        });
        server.listen(3000);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    但是,实际工作中,我们想要进程守护,会用 pm2 这个包,开启多个进程。

    使用 send 和 on 来进行通讯

  • 相关阅读:
    在.net中通过自定义LoggerProvider将日志保存到数据库方法(以mysql为例)
    【CAN】CAN基础概念5
    数据结构复习笔记6.2:图的存储和遍历
    Android画中画
    大学生川菜网页制作教程 学生HTML静态美食菜品网页设计作业成品 简单网页制作代码 学生美食网页作品免费设计
    QT—3D绘图
    如何降低云计算成本?
    Linux调试器-gdb使用
    “小程序:改变电商行业的新趋势“
    JSP图书销售管理系统
  • 原文地址:https://blog.csdn.net/x_chengqq/article/details/126931289