【问题标题】:pm2 can't fork nodejs which is contain origin cluster codepm2 不能 fork 包含原始集群代码的 nodejs
【发布时间】:2021-02-24 05:11:55
【问题描述】:

我的应用程序是一个在内部使用原始 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', (worker, 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) 在子进程。 (内部/集群/worker.js:32:12) 在 ChildProcess.emit (events.js:315:20) 在发射(内部/child_process.js:903:12) 在 processTicksAndRejections (internal/process/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) 在子进程。 (内部/集群/worker.js:32:12) 在 ChildProcess.emit (events.js:315:20) 在发射(内部/child_process.js:903:12) 在 processTicksAndRejections (internal/process/task_queues.js:81:21)

【问题讨论】:

    标签: node.js pm2


    【解决方案1】:

    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/

    【讨论】:

      【解决方案2】:

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

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

      但新的问题出现了

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

      此代码不起作用

      我用node 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",num:msg.num,err})
                  }
                  
              }
          })
      }
      
      //child process of rabbitmq
      master['rabbitmq'] = {
          childGroup:[],
          workIndex:0,
          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',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)
                      mq.send({des:"res",num:msg.num,status:true,data:result})
                  }catch(err){
                      mq.send({des:"res",num:msg.num,err})
                  }
                  
              }
          })
      }
      
      forkNewMQ()
      
      
      //child process of redis
      master['redis'] = {
          childGroup:[],
          workIndex:0,
          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',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)
                      redis.send({des:"res",num:msg.num,status:true,data:result})
                  }catch(err){
                      redis.send({des:"res",num:msg.num,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}
      

      node dist/main log 应该是

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-05
        • 1970-01-01
        • 2018-04-02
        • 2018-01-17
        • 1970-01-01
        • 2015-08-05
        • 1970-01-01
        • 2016-08-02
        相关资源
        最近更新 更多