优雅地关闭节点实例,而不会中途停止任何操作。

12 浏览
0 Comments

优雅地关闭节点实例,而不会中途停止任何操作。

请注意,这个问题不是关于在进程崩溃时保持其运行,或者在进行新部署时重新启动它。这个问题是关于如何在不中断待处理操作的情况下重新启动。\n我有一个非常繁忙的Node应用程序,每秒接收大量的请求。我的应用程序运行的函数在返回结果之前需要相当长的时间(例如:通过API上传YouTube视频)。\n我遇到的问题是,当我部署新版本的应用程序时,进程会重新启动,结果任何处于“待处理”状态的操作也会被杀掉。这意味着10个YouTube上传可能会被杀掉并需要重新启动。\n现在:\n

    \n

  • 清空事件队列几乎是不可能的,因为我可能要等很长时间
  • \n

  • 按原样杀死进程证明是有问题的
  • \n

\n理想的解决方案是确保任何现有的进行中的请求得到满足,但使用新部署的代码来处理任何新的请求。\n一个可能的想法是:\n

    \n

  • 有一个接受连接的主进程。这个进程永远不会改变
  • \n

  • 当有更新时,向这个进程发送一个信号,它将重新加载“runner”
  • \n

  • 此时,任何新的请求都将通过更新后的runner处理
  • \n

\n只有当您想要更新接受连接的主进程时,才必须真正重新启动进程本身。\n这种方法是否有人已经实现过?是否有一个模块可以做到这一点?还是说这个方法过于复杂了?\n更新\n有趣的答案:https://stackoverflow.com/a/10711410/829771 然而,等待事件循环为空来重新启动进程是不现实的。\n但是,这里还有另一层复杂性:如果服务器有定时器,例如每5分钟运行一次任务,根据我上面写的,你会有两个定时器在运行。因此,“过时”的进程必须收到一个信号并监听它,并在收到信号时停止任何“后台”操作。请记住,这不是理论 -- 我的应用程序中确实有setInterval()。

0
0 Comments

问题的原因是,当需要优雅地关闭节点实例时,需要处理未完成的下载任务。操作系统会自动处理其他的清理工作,所以没有必要手动清理所有内部节点的内容。这样做可能比应用本身更复杂。

解决方法是,在主应用程序中启动至少两个“worker”进程,使用不同的端口。在主应用程序中实现一个简单的面板,可以在面板上启动/暂停这些进程,并将所有的“任务”发送到其中一个进程中。当需要部署应用程序时,只需暂停其中一个进程,等待上传任务完成后,再进行部署,然后再移动到第二个进程。额外的好处是,这样可以提供冗余。如果实现一个简单的“ping”命令,可以在进程死亡时自动路由连接。

还可以实现一个函数,用于返回未完成的上传列表以及正在运行的计时器,然后“主”应用程序可以自动终止该运行器。实际上,如果计时器触发的操作不是原子操作,应该在开始时将其添加到列表中,在结束时将其移除,即使计时器仍在计时也没有问题。在触发事件之前的20秒将其放入列表中,就不会出现在获取“进程”列表、杀死进程和事件触发之间出现的竞争条件问题。

0