The introduction

Node, as a simple back-end service, is used in the current project. As it undertakes more and more online business services, it requires the stability of the service side, and the most important point is the service survival. The ability to restart automatically after a process terminates.

forever

Forever is a simple command-line tool that ensures that a given script keeps running. Forever operates entirely on the command line. Under the Forever process, a node child process is created and monitored by Monitor. Once a file is updated or a process hangs, Forever automatically restarts the Node server to ensure that the application is running properly.

So take a look at Forever’s project. The code address of the main process control aspect.

The start method

let child_process = require('child_process')
let spawn = child_process.spawn

Monitor.prototype.start = function(restart) { var self = this, child; child = this.trySpawn(); .return this;
};
Monitor.prototype.trySpawn = function () {
  var run = this.parser(this.command, this.args.slice()),
      stats;

  return spawn(run.command, run.args, this.spawnWith);
};
Copy the code

The core is to use the Spawn of the Node API to create the child process, which is the actual Node side service we need to run.

communication

The communication core of the parent process is to keep alive, mainly listening for the child process, that is, the exit event that needs to be daemon

  child.on('exit'.function (code, signal) {
    var spinning = Date.now() - self.ctime < self.minUptime;
    child.removeListener('message', onMessage);
    self.emit('exit:code', code, signal);

    function letChildDie() {
      self.running = false;
      self.forceStop = false;
      self.emit('exit', self, spinning);
    }

    function restartChild() {
      self.forceRestart = false;
      process.nextTick(function () {
        self.start(true);
      });
    }

    self.times++;

    if(self.forceStop || (self.times >= self.max && ! self.forceRestart) || (spinning && typeof self.spinSleepTime ! = ='number') && !self.forceRestart) {
      letChildDie();
    }
    else if (spinning) {
      setTimeout(restartChild, self.spinSleepTime);
    }
    else{ restartChild(); }});Copy the code

The logic is very simple, there are two scenarios, one is to want the child process not to start again, generally is killed by external control; One is a restart after an unexpected exit, as determined by a SPINNING value, that is, there is a restart interval after exit.

Parent-child process communication

Message event to listen, send method to send events, parent-child communication can be used as an external control implementation. One more detail to note is that the Node backend service is running a lot of logs, and the console output is placed in the child process. If you want to expose the console output, you can use the options.stdio property.

conclusion

There are a lot of scenarios to keep alive, so you can use the Forever library to handle them, along with monitoring and logging functions, to better ensure the stability of the online environment.