有没有办法确保我部署的heroku服务/应用程序在更新期间保持运行



目前我正在Heroku上部署一项服务。该服务轮询一个api,并使用Node.js中的常规setInterval方法来获取新信息(我不能使用websocket,因为我不介意使用的api(。

就像某人开发的任何程序或应用程序一样,它需要定期更新。我的问题是,在heroku上更新我的应用程序的最佳方式是什么,这样当我将新的更改推向生产时,就不会阻止应用程序运行?原因是我不想错过api中的新数据。

我的第一个想法是有某种冗余,至少有两个服务器在运行应用程序,当一个服务器更新时,另一个服务器运行,反之亦然。然而,我不确定这是由heroku自动完成的,还是没有,我如何确保我设置了这样的东西,在更新过程中不会错过一段数据。即使丢失API中的一条新数据,我们也不能选择。

有其他方法可以做到这一点吗?

在nodejs或Heroku上没有实现零停机更新的自动过程。如果您不能或不希望通过更新源文件、停止并重新启动服务器来减少停机时间,那么您将不得不使用两个独立的进程来执行您已经考虑过的操作,其中一个进程继续运行,另一个进程正在更新,反之亦然。

除了轮询一些外部API之外,你没有说这个应用程序做什么,也没有说它对从API获得的数据做什么。这两者都与您将如何实现这一点的细节有关。

为了便于说明,我将对这些未知因素做一些假设。让我们假设这个服务应用程序只使用API中新找到的数据更新数据库,而不启动自己的任何服务器进程。

在这种情况下,您可以设计您的服务,这样您就可以运行两个实例,并且它接受一个命令行参数,决定它是否应该开始轮询API,或者它是否应该启动并等待。您为服务器提供自己的控制端口(通常是一个http服务器,它只接受本地请求,而不接受来自互联网的请求(,允许您向其发送命令。而且,您可以通过命令行参数或环境变量来配置控制端口使用的端口,这样您就可以启动应用程序的多个实例,每个实例都有不同的控制端口。

然后是一系列事件:

  1. 启动服务器的一个实例,并向它传递命令行参数,告诉它立即开始轮询
  2. 它以这种方式运行,直到您准备好更新为止
  3. 然后,当您准备好更新时,您将更新本地代码,这不会影响正在运行的实例,因为它的代码已经加载
  4. 更新后,您启动服务器的第二个实例(运行新代码(,并向它传递一个命令行参数,告诉它不要开始轮询。此时,您有两个正在运行的服务实例,一个(运行旧代码(正在轮询API,另一个(正在运行新代码(处于备用状态
  5. 然后,你在每个应用程序的控制端口上向它们发送一个命令。第一个应用程序(运行旧代码(被告知停止轮询并关闭。第二个应用程序(运行新代码(被告知开始轮询
  6. 现在,您可以启动并运行新代码,并且可以在没有任何中断的情况下进行轮询

您可以使用自己喜欢的shell脚本自动切换。

如果您的服务器也有一个传入的http服务器来服务来自internet的请求,那么告诉第二个实例开始轮询的命令也必须在上一个实例关闭它们的internet请求后启动其http服务器。

使用负载平衡器或动态可配置的代理,您可以让两个web服务器都在不同的本地端口上运行,并动态更改负载平衡器/代理配置,以便在关闭第一个实例之前将所有传入请求路由到第二个实例,并且不会错过任何传入的web请求。

最新更新