正确停止、等待和重置Node.js Heroku进程

6

我还没有部署,但是我不确定如何做到这一点。

我有一个应用程序使用了很多后台进程。也就是说,在响应被发送之后,仍然会有与该响应相关的函数在后台执行。因此,我想要做类似于这样的事情:

var server = http.createServer(app).listen(80)

process.on('SIGINT', function () {
  server.close()
  setTimeout(function () {
    process.exit()
  }, 30000) // Wait 30 seconds before exiting
})

我不确定这是否正确。更多假设:

  • 这些后台进程至关重要。但是它们可能需要1-2秒的时间,而不是30秒。尽管如此,出于安全考虑,我仍想设置30秒的延迟。
  • 这应该适用于重新启动进程(例如,使用forever)和停止进程
  • Heroku(或任何其他进程)通过process向node.js发送哪些信号?我是否需要以不同方式处理它们?
  • 我是否需要以不同的方式处理uncaughtException

谢谢

2个回答

10

明白了。当Heroku关闭时,它发送一个SIGTERM信号。如果进程在10秒内没有退出,则发送SIGKILL信号。因此,下面的代码就足够了:

process.on('SIGTERM', server.close.bind(server))

https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm

假设10秒足以让后台进程完成。

基本上,在发送“退出”信号之前,发送“关闭”信号x秒,应该就可以了。


2
我认为你最好使用一个工作进程来处理那些后台任务(在Heroku上使用工作进程)。
这样既可以让你的Web服务器尽可能快地为用户提供服务,也可以在扩展时更好地控制(例如运行3个Web进程和2个工作进程)。
你可以使用Redis的发布/订阅功能来提交作业到工作进程(或使用库来完成,如http://learnboost.github.com/kue/)。
这样,当Web进程重新启动/死亡等情况发生时,它不会对待处理的后台作业产生任何影响,而当工作进程重新启动时,它只会消耗待处理的作业并进行处理,因此你不会因重新启动而丢失任何作业。

  1. 这些任务是数据库任务,所以我认为使用工作程序没有意义。当我将任务排队时,它可能已经完成了。
  2. 我不打算添加另一个数据库。
  3. 我不想要多个堆栈。
- Jonathan Ong
2
因此,要实现类似于作业队列的东西,这样当 dyno 重新启动时,它可以处理挂起的作业,并且不会由于重新启动而失去任何内容。在我看来,这比设置一个超时并希望没有任何东西被终止的策略要更加稳健。(如果机器完全崩溃而未杀死进程,也会得到覆盖)。 - Gal Ben-Haim
答案要简单得多-监听SIGTERM事件而不是SIGINTSIGKILL:https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm - Jonathan Ong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接