【问题标题】:Is there a way to ensure that a service/app that I have deployed heroku, stays running during an update?有没有办法确保我部署 heroku 的服务/应用程序在更新期间保持运行?
【发布时间】:2021-11-19 02:08:48
【问题描述】:

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

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

我的第一个想法是要有某种冗余,其中至少有 2 台服务器运行应用程序,并且当一个服务器更新另一个运行时,反之亦然。然而,我不确定这是否是由 heroku 自动完成的,或者如果没有,我如何确保我设置这样的东西在更新期间不会错过一条数据。甚至遗漏 API 中的一条新数据也不是我们的选择。

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

【问题讨论】:

    标签: node.js heroku server cloud


    【解决方案1】:

    在 nodejs 或 Heroku 中没有零停机时间更新的自动过程。如果您不能或不希望更新源文件的停机时间,然后停止并重新启动服务器,那么您将不得不做一些事情,就像您已经在考虑使用两个单独的进程一样,一个继续运行而另一个正在运行更新,然后反之亦然。

    除了轮询一些外部 API 之外,您还没有过多地说明此应用程序的功能,并且您还没有说明它如何处理从该 API 获取的数据。这两者都与您将如何实现这一点的细节有关。

    为了便于说明,我将对这些未知数做一些假设。假设这个服务应用只是用 API 中新发现的数据更新了一个数据库,并没有启动它自己的任何服务器进程。

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

    接下来是一系列事件:

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

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

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

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

    【讨论】:

    • 非常感谢您的深入解释。 @jfriend00 我想理论上我可以在 heroku 上运行 2 个生产应用程序并一次更新一个,对吗?在这里寻找最快的解决方案。或者有更好的方法吗?
    • @MarioLopez - 好吧,运行两个应用程序,你必须有某种负载均衡器来分散它们之间的负载,然后当你关闭另一个时将所有请求转移到一个升级。但是,是的,运行着许多服务器的大型站点就是这样进行升级的。
    • @MarioLopez - 如果这回答了您的问题,那么您可以通过单击答案左侧的复选标记在此处向社区表明这一点。这也将为您在此处遵循正确的程序赢得一些声誉积分。
    • 非常感谢您的回复!刚刚让你的答案:)
    • 想到的另一个问题是,理论上只有在向服务器发送 http 请求时才需要负载均衡器,对吧?但是,如果我们只是更新数据库,就不需要负载均衡器了吗?
    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2017-06-12
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多