Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node.js 多进程自动守护管理 #29

Open
chenshenhai opened this issue Feb 20, 2018 · 0 comments
Open

Node.js 多进程自动守护管理 #29

chenshenhai opened this issue Feb 20, 2018 · 0 comments
Labels

Comments

@chenshenhai
Copy link
Owner

chenshenhai commented Feb 20, 2018

前言:放假在家阅读了cfork模块的源码,发现其中的进程重启管理很有意思,值得学习,模仿该功能自己写了简单的进程fork和refork的核心代码片段

主要功能

  • 启动多进程
  • 子进程退出自动fork新进程

多进程启动和自动守护代码

./fork.js

const cluster = require('cluster');
const os = require('os');
const cupCount = os.cpus().length; 

module.exports = fork;

/**
 * @name {Function} frok
 * @param {Object} options 
 * - {String} exec [必填]进程文件 
 * - {Array} args [必填]进程命令参数
 * - {Boolean} silent 是否要发送输 默认false
 * - {Number} count, 进程数量 默认为CPU核数
 * - {Boolean} refork, 当work进程退出或者断开,是否需要重启, 默认是true
 */
function fork (options = {}) {
  if (cluster.isWorker) {
    return;
  }

  if( !options.exec ) {
    return;
  }

  const totalWorkerCount = options.count > 0 ? options.count : cupCount;

  let opts = {
    exec: options.exec
  }; 
  let newWorker;
  let workerCount = 0;

  // 启动主进程
  cluster.setupMaster(opts);

  for( let i=0; i<totalWorkerCount; i++ ) { 
    // 根据配置启动相关的子进程
    newWorker = forkWorker();
  }

  /**
   * @name forkWorker worker进程启动方法
   * @return {Object} 
   */
  function forkWorker() { 
    // 判断进程是否超过CPU数量
    if( workerCount >= cupCount ) {
      return;
    }
    // 如果不超过CPU数量的就fork worker进程
    workerCount ++;
    return cluster.fork();
  }

  /**
   * @name reforkWorker worker进程重启方法
   * @return {Object} 
   */
  function reforkWorker() {
    return forkWorker()
  }

  // 监听进程是否退出
  cluster.on('exit', (worker, code, signal) => { 
    console.log( `the worker pid  ${worker.process.pid} has exited` )
    // 重新fork进程
    reforkWorker();
  });

  // 监听进程是否断开连接
  cluster.on('disconnect', (worker) => { 
    console.log( `the worker pid  ${worker.process.pid} has disconnected` )
    let isDead = worker.isDead && worker.isDead();
    if ( isDead ) {
      console.log( `the worker pid  ${worker.process.pid} is dead` )
      return;
    } 
    workerCount --;
    reforkWorker();
  });

  return cluster;
}

多进程守护使用

index.js

const fork = require('./fork');

fork({
  exec: './worker'
})

worker.js

const http = require('http');
const process = require('process');

const PORT = 3001;

const server = http.createServer((req, res) => {
  res.write('hello fork');
  res.end();
});

server.listen(PORT, () => {
  console.log(`the server is start at port ${PORT}, PID=${process.pid}`)
})

测试效果

启动多进程守护

2018-02-20 3 47 53

手动删除其中的一个子进程

2018-02-20 3 48 27

可以看出当监听到子进程退出后,就会自动重启一个新的进程,保证指定数量多进程的执行

参考代码

https://github.com/node-modules/cfork/blob/master/index.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant