在 Heroku 上进行热部署,无需停机

Posted

技术标签:

【中文标题】在 Heroku 上进行热部署,无需停机【英文标题】:Hot deploy on Heroku with no downtime 【发布时间】:2011-02-03 09:18:37 【问题描述】:

推送到 Heroku 的一个不好的方面是我必须在运行我的数据库迁移之前推送代码(并且服务器会自动重新启动)。

这显然会导致用户在没有新表/属性的情况下使用新代码浏览网站时出现大约 500 个错误:Heroku 提出的解决方案是使用维护模式,但我想要一种没有缺点的方法让我的 webapp 运行每次!

有办法吗?以 Capistrano 为例:

我准备要在新目录中部署的代码 我运行(向后)迁移,旧代码继续完美运行 我将 mongrel 实例切换到新目录并重新启动服务器

...而且我没有停机时间!

【问题讨论】:

【参考方案1】:

目前,我认为没有停机时间就可以做到这一点。我也讨厌。

这个控制台命令在我能想到的最短时间内完成

git push heroku master && 
heroku maintenance:on && 
sleep 5 && 
heroku run rails db:migrate && 
sleep 3 && 
heroku ps:restart && 
heroku maintenance:off
    git push heroku master 将master分支推送到heroku heroku maintenance:on 进行维护,所以没有 500 秒 sleep 5 让 dynos 启动新代码(没有它,迁移可能会失败) heroku run rails db:migrate 进行实际迁移 heroku ps:restart 经验不足,重新启动确保新的 dynos 具有最新的架构 heroku maintenance:off轮巡维护

如果您有多个应用程序,您可能需要在所有 heroku 命令后面添加-a <app name>

在 Mac OSX 的终端中,只需一个命令即可连续运行这些命令。

【讨论】:

【参考方案2】:

如果您能够同时使用同一应用的两个版本,Heroku 现在具有预启动功能。

https://devcenter.heroku.com/articles/preboot

【讨论】:

【参考方案3】:

我首先提交迁移,运行它们,然后推送其余代码。像这样添加一个文件:

git commit -m 'added migration' -- db/migrate/2012-your-migration.rb

【讨论】:

【参考方案4】:

当 Heroku 重新启动您的应用程序时,您实际上会有一些停机时间。他们有一个名为 Preboot 的新功能,可以在取出旧的测功机之前启动新的测功机:https://devcenter.heroku.com/articles/labs-preboot/

关于数据库迁移,该文章链接到这篇文章,了解如何处理该问题:http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/

【讨论】:

【参考方案5】:

您可以设置第二个 Heroku 应用程序,该应用程序指向与您的主要生产应用程序相同的数据库,并使用辅助应用程序在不中断生产的情况下运行您的数据库迁移(假设迁移不会破坏您应用程序的先前版本)。

我们将 Heroku 应用称为 PRODUCTIONSTAGING

你的部署顺序会变成这样:

    将新代码部署到STAGINGgit push heroku stagingSTAGING 上运行数据库迁移(以更新 PROD db)heroku run -a staging-app rake db:migrate 将新代码部署到 PRODUCTIONgit push heroku production

staging 应用程序不会花费您任何费用,因为您不需要超过 Heroku 的免费层级,而且设置一个 rake 部署脚本来自动为您执行此操作非常简单。

祝你好运!

【讨论】:

我相信 Heroku 会保持你的旧 dynos 直到新 slug 的编译完成,所以你的网站应该在第 3 步运行时保持可用。我想在 Heroku 将路由从旧的 dyno 切换到新的 dyno 时可能会有一些暂时的停机时间,但应该非常少。 如果您真的将其用作暂存环境,我不确定将暂存环境链接到生产数据库是否是一个好主意。 STAGING 只是一个示例名称,我并不是建议您应该为此重用用于测试预生产代码的相同环境。那是个坏主意。在这种情况下,您将创建生产应用程序配置的专用第二个副本,专门用于部署过程。你可以叫它任何东西。【参考方案6】:

在某种程度上改进这个过程的唯一方法是这个人建议的。不过,这仍然不是一个热部署方案:

http://casperfabricius.com/site/2009/09/20/manage-and-rollback-heroku-deployments-capistrano-style/

我建议的一件事是先将您的迁移推送到 Heroku,然后在推送代码库之前运行它们。这将需要将迁移作为独立提交提交并每次手动推送它们(这并不理想)。我很惊讶,现在 Heroku 上托管的所有大型应用程序都没有更好的解决方案来解决这个问题。

【讨论】:

【参考方案7】:

Heroku 无法通过 capistrano 部署。你被heroku发布的工具屏蔽了。

无停机系统在所有情况下都是不可能的。如何在不停止服务器的情况下进行重大更改来更改架构。如果你不停止它,你可以避免一些变化,你的数据库可能会不一致。所以使用维护页面是正常的解决方案。

如果您想要一个避免问题的小解决方案是在两台服务器上进行平衡。迁移期间只有读取数据库的一种。您可以在迁移期间切换到此实例,避免进入维护页面。迁移后,您会回到您的主人那里。

【讨论】:

嗨 shingara,我很抱歉,但我不同意你的看法。我不想为此使用负载平衡:Heroku 的一大特点是必要的“透明”云能力,我想使用这个功能......为了在 Heroku 中进行负载平衡,我必须维护两个不同的应用程序只读数据库可能会给我的用户带来问题。无停机系统并非不可能。我使用正确的系统解释没有停机时间。如果发生重大变化而没有复古兼容的数据库架构的可能性,我可以使用维护页面:但这是我所有案例的 5%... 例如,您可以通过使用 CouchDB 来避免此答案中描述的问题。

以上是关于在 Heroku 上进行热部署,无需停机的主要内容,如果未能解决你的问题,请参考以下文章

重识Nginx - 05 热部署_不停机更换新版本的nginx

sh Laravel Forge无需停机即可部署脚本

无需更改代码即可重新部署 Heroku 应用

使用 Maven 和 NetBeans 在 Tomcat 上进行增量热部署

FastAPI环境部署

如何在集群环境中进行零停机时间部署?