Node.js: What is a good way to automatically restart a node server that is not responding?

I have inherited a node.js / Express application that is a bit messy. It gets stuck regularly and rather randomly and does not respond to any request until it is restarted.

I suspect that something inside the application is blocking and either getting stuck in a loop or making a request to an external api without using the appropriate Async methods, and never gets a response and never picks a time when the server just stops responding but doesn't crash .

Obviously, I would like to find the criminal code and fix the problem, but at the same time I would like to find a way to automatically restart the server when it stops responding.

To test the solutions locally (since I don’t know the real culprit), I created the following express route that mimics the exact behavior that I get.

app.get('/block-block-block', function (req, res){ 
  for(;;) {}
};

The question I have is that the specified route is being routed (which immediately stops the server from answering anything), is there a way to detect the lock inside the node internally and restart or close? And if not, is this a good solution to check when the server is not responding and rebooting it?

Most of the searches I performed lead me to tools like forever and PM2 . They work great if your application crashes, but I really do not see any options for restarting when the application blocks radomies.

+4
3

, , Node. Migg , - , , .

, Node child_process fork, Node ping- , , . , Forever PM2. , , .

, , . , ES2015 . , .

var fork = require('child_process').fork;
var server, heartbeat; 

function startServer () {
  console.log('Starting server');
  server = fork('server');

  //when the server goes down restart it
  server.on('close', (code) => {
    startServer();
  });

  //when server sends a heartbeat message save it
  server.on('message', (message) => {
    heartbeat = message ? message.heartbeat : null;
  });

  //ask the server for a heartbeat
  server.send({request: 'heartbeat'});

  //wait 5 seconds and check if the server responded
  setTimeout(checkHeartbeat, 5000);
}

function checkHeartbeat() {
  if(heartbeat) {
    console.log('Server is alive');

    //clear the heart beat and send request for a new one
    heartbeat = null; 
    server.send({request: 'heartbeat'});

    //set another hearbeat check
    setTimeout(checkHeartbeat, 5000);

  } else {
    console.log('Server looks stuck...killing');
    server.kill();
  }
}

startServer();

server.js Node, .

, heartbeat.

//listen and respond to heartbeat request from parent
process.on('message', (message) => {
  if(message && message.request === 'heartbeat') {
    process.send({heartbeat: 'thump'});
  }
});

, , , ( !)

//block the even loop after 30 seconds 
setTimeout(() => {
  for(;;){}
}, 30000);
+3

, , .

pm2. , , . :

pm2 start big-array.js --max-memory-restart 20M

ecosystem.json:

{
    "max_memory_restart" : "20M"
}

node.js . , . , .

/

, . , - , . process.nextTick.

, , , process.nextTick X , , process.exit(1), , pm2 .

, . , process.exit.

, https://www.joyent.com/developers/node/debug. MDB, , . , .

!

+2

, , , . .

- . , - . , . , , , , , , , .

+1

Source: https://habr.com/ru/post/1627196/


All Articles