手动结束(Ctrl + C,kill命令等)后如何正常退出Node程序?

时间:2019-02-22 11:07:01

标签: node.js

我希望我的Node程序在退出之前执行一些任务(例如,关闭数据库连接并删除一些对象),即使该程序已手动停止(例如,通过Ctrl + C或kill命令) )。这可能吗?

我尝试使用process.on('exit')process.on('SIGINT'),但是我的任务从未在程序退出之前完成,而且我不确定它是否也处理kill命令:

require('dotenv').config()
const log = require('./middleware/log')
const error = require('./middleware/error')
const mongoose = require('mongoose')
const puppeteer = require('puppeteer')
const cleanup = require('./middleware/cleanup');

(async () => {

  // handle Ctrl+C
  process.on('SIGINT', () => {
    cleanup(browser) // this never finishes before the program ends
    process.exit(2)
  })

  // log program exit
  process.on('exit', (code) => {
    if (code === 2) {
      log('Program exited manually.')
    } else if (code === 1) {
      log('Program crashed.')
    } else {
      log('Program exited.')
    }
    cleanup(browser) // I've tried putting it here too, but it still doesn't finish before the program ends
    process.exit(code)
  })

  await mongoose.connect(
    'mongodb://app:' + process.env.MONGO_PW_DEV + '@' + process.env.MONGO_IP_DEV + ':' + process.env.MONGO_PORT_DEV + '/' + process.env.MONGO_DB_DEV,
    {
      useNewUrlParser: true
    }
  )

  const browser = await puppeteer.launch({ headless: true })
  page = await browser.newPage()

  // do stuff

  cleanup(browser)

})().catch(async (err) => {
  cleanup(browser)
  error(err)
})

这是我的清理功能:

const mongoose = require('mongoose')

module.exports = (browser) => {
  mongoose.disconnect()
    .then(res => {
      browser.close()
        .then(res => {
          return
        })
    })
}

2 个答案:

答案 0 :(得分:1)

对于NodeJS中的正常关机,请使用kill signal

  

信号是发送到进程或设备的异步通知   通知发生事件的特定线程。

See more about Node.js Signal Events

当NodeJS进程接收到信号时,将发出信号事件 例如'SIGINT','SIGTERM'等

    在终端中使用+ C生成的
  • 'SIGINT'。
  • “ SIGTERM”信号是用于导致程序终止的通用信号。与“ SIGKILL”不同,此信号可以被阻止,处理和忽略。礼貌地要求程序终止是正常的方法。
  • shell命令kill默认情况下会生成“ SIGTERM”。

More about Termination Signals

我们只需要添加处理程序即可接收“ SIGTERM”信号:

process.on('SIGTERM', () => {
  console.log('Signal received.');
});

对于您而言,我认为流程事件可能会有所帮助

此外,在正常情况下,为了监听退出事件并设置程序以执行其他任务,process可以发出诸如beforeExitexit之类的事件

See 'process' events

  

事件:'exit'当Node.js进程处于运行状态时,将发出'exit'事件。   由于以下任一原因而即将退出:

     
      
  • process.exit()方法被显式调用;
  •   
  • Node.js事件循环不再需要执行任何其他工作。
  •   
     

目前无法阻止事件循环的退出   然后,所有“退出”侦听器都已完成运行Node.js   过程将终止。

希望对您有所帮助! :)

More about Graceful shutdown in NodeJS

答案 1 :(得分:0)

由于您尚未共享代码,但是可以尝试类似的操作

      process.on('SIGTERM', () => {
      console.info('SIGTERM signal received.');
      console.log('Closing http server.');
      expressServer.close(() => {
        console.log('Http server closed.');
        // boolean means [force], see in mongoose doc
        mongoose.connection.close(false, () => {
          console.log('MongoDb connection closed.');
          process.exit(0);
        });
      });
   });