pm2无法派生包含原始群集代码的nodejs

问题描述

我的应用是在内部使用原始nodejs集群代码的应用程序,并由node ./dist/main.js运行 但是当我使用pm2 start ./dist/main.js

时会出错
//my code

import cluster from 'cluster'
import http from 'http'

if(cluster.isMaster){
    (async()=>{
        const master = await (await import('./master'))
        async function onMsg(pid:number,type?:string,num?:number,data?:{db:any,apiName:any,args:Array<any>}){
            console.log(`master receiving message from cluster ${pid}`)
            try{
                let result = await master.publishMission(type,data)
                // console.log(`${type} finish mission and send back to koa cluster ${pid}`)
                cluster.workers[pid].send({num:num,status:true,data:result})
            }catch(err){
                cluster.workers[pid].send({num:num,err})
            }
        }
        //cluster nums
        for(let i=0;i<1;i++){
            cluster.fork()
        }
        cluster.on('message',(worker,msg)=>{
            onMsg(worker.id,...msg)
        })
        cluster.on('exit',code,signal) => {
            console.log('worker %d died (%s). restarting...',worker.process.pid,signal || code);
            cluster.fork();
          });
    })()
}else{
    (async()=>{
        const app = await (await import('./app')).app
        try{
            http.createServer(app).listen(5000)`enter code here`
            console.log("fork new koa server",process.pid)
        }catch(err){
            console.log(err)
        }
    })()
}

//错误日志 TypeError:发现不可调用的@@ iterator 在EventEmitter。 (C:\ Users \ yany \ project \ Jmrh_Warehouse \ src \ main.ts:22:13) 在EventEmitter.emit(events.js:315:20) 在工人。 (内部/集群/master.js:174:13) 在Worker.emit(events.js:315:20) 在ChildProcess。 (内部/集群/worker.js:32:12) 在ChildProcess.emit(events.js:315:20) 发出时(internal / child_process.js:903:12) 在processticksAndRejections(内部/进程/task_queues.js:81:21) TypeError:发现不可调用的@@ iterator 在EventEmitter。 (C:\ Users \ yany \ project \ Jmrh_Warehouse \ src \ main.ts:22:13) 在EventEmitter.emit(events.js:315:20) 在工人。 (内部/集群/master.js:174:13) 在Worker.emit(events.js:315:20) 在ChildProcess。 (内部/集群/worker.js:32:12) 在ChildProcess.emit(events.js:315:20) 发出时(internal / child_process.js:903:12) 在processticksAndRejections(internal / process / task_queues.js:81:21)

解决方法

pm2在内部实现集群。

因此,端口共享可能存在问题。

其中:dist/main.js

(async()=>{
        const app = await (await import('./app')).app
        try{
            http.createServer(app).listen(5000)`enter code here`
            console.log("fork new koa server",process.pid)
        }catch(err){
            console.log(err)
        }
    })()

pm2 start dist/main.js -i max可能有效。 -i以集群模式启动pm2。

https://pm2.keymetrics.io/docs/usage/cluster-mode/

,

通过使用pm2 start dist/main.js -i 1,此错误结束

因此,当使用pm2 fork时,可能会禁用内部的集群消息转换

但是出现了新问题

const master = await (await import('./master'))

此代码无效

当我使用节点dist / main.js但不能在pm2中工作时很好

import * as cl from 'child_process'
import {EventEmitter} from 'events'

const event = new EventEmitter()
const autoReboot = false
var count = 0

console.log("fine")

interface masterStore{
    [typeOfChild:string]:{
        childGroup?:Array<cl.ChildProcess>,workIndex:number,maxNum?:number,}
}

var master:masterStore={}

//child process of database
master['mongodb'] = {
    childGroup:[],workIndex:0,maxNum:1
}

for(let i =0;i<master['mongodb'].maxNum;i++){
    forkNewDB()
}

function forkNewDB(){
    var db = cl.fork(`${__dirname}/data/index.js`)
    master['mongodb'].childGroup.push(db)
    db.on('exit',(signal)=>{
        console.log(`db process ${db.pid} exit with code ${signal}`)
        let index = master['mongodb'].childGroup.findIndex(el=>el.pid==db.pid)
        master['mongodb'].childGroup.splice(index,1)
        if(autoReboot){
            forkNewDB()
        }
    })
    db.on('message',async (msg:{des:string,type:string,ev:string,result?:any,err?:any,data?:any,num?:any})=>{
        if(msg.des=="res"){
            event.emit(msg.ev,{msg})
        }else{
            try{
                let result = await publishMission(msg.type,msg.data)
                db.send({des:"res",num:msg.num,status:true,data:result})
            }catch(err){
                db.send({des:"res",err})
            }
            
        }
    })
}

//child process of rabbitmq
master['rabbitmq'] = {
    childGroup:[],maxNum:1
}

function forkNewMQ(){
    var mq = cl.fork(`${__dirname}/mq/index.js`)
    master['rabbitmq'].childGroup.push(mq)
    mq.on('exit',(signal)=>{
        console.log(`mq process ${mq.pid} exit with code ${signal}`)
        master['rabbitmq'].childGroup.splice(0,1)
        if(autoReboot){
            forkNewMQ()
        }
    })
    mq.on('message',msg.data)
                mq.send({des:"res",data:result})
            }catch(err){
                mq.send({des:"res",err})
            }
            
        }
    })
}

forkNewMQ()


//child process of redis
master['redis'] = {
    childGroup:[],maxNum:1
}

function forkNewRedis(){
    var redis = cl.fork(`${__dirname}/redis/index.js`)
    master['redis'].childGroup.push(redis)
    redis.on('exit',(signal)=>{
        console.log(`redis process ${redis.pid} exit with code ${signal}`)
        let index = master['redis'].childGroup.findIndex(el=>el.pid==redis.pid)
        master['redis'].childGroup.splice(index,1)
        if(autoReboot){
            forkNewRedis()
        }
    })
    redis.on('message',msg.data)
                redis.send({des:"res",data:result})
            }catch(err){
                redis.send({des:"res",err})
            }
            
        }
    })
}

forkNewRedis()

//init message publish
function publishMission(type?:string,data?:{db:any,apiName:any,args:Array<any>}):Promise<any>{
    return new Promise(async (res,rej)=>{
        try{
            let tmp = master[type].workIndex
            master[type].workIndex++
            master[type].workIndex=master[type].workIndex%master[type].maxNum
            let ev = count+""
            // console.log(`master publish mission to ${type}`)
            master[type].childGroup[tmp].send({data,ev,des:"req"})
            count++
            event.once(ev,(result)=>{
                if(!result.msg.err){
                    res(result.msg.result)
                }else{
                    rej(result.msg.err)
                }
                event.removeListener(ev,()=>{})
            })
        }catch(err){
            rej(err)
        }
    })
}


export{publishMission}

节点dist /主日志应为

fine
child process 10116 rabbitmq is ready
fork new koa server 15948
child process 10008 create DB thread 1