12

Is it possible to do something like the Github zero downtime deploy on Heroku using Unicorn on the Cedar stack?

I'm not entirely sure how the restart works on Heroku and what control we have over restarting processes, but I like the possibility of zero downtime deploys and up until now, from what I've read, it's not possible

There are a few things that would be required for this to work.

  1. First off, we'd need backwards compatible migrations. I leave that up to our team to figure out.
  2. Secondly, we'd want to migrate the db right after a push, but before the restart (assuming our migrations are fully backwards compatible, this should not affect anything)
  3. Thirdly, we'd want to instruct Unicorn to launch a new master process and fork some workers, then swap the PIDs and gracefully shut down the old process/workers

I've scoured the docs but I can't find anything that would indicate this is possible on Heroku. Any thoughts?

4

4 回答 4

26

我无法解决迁移问题,但关于重新启动进程和避免等待时间的部分:

heroku 有一个测试版功能,称为 preboot。部署后,它首先启动您的新测功机并等待一段时间,然后切换流量并杀死旧的:

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

我还写了一篇博客文章,其中对我的应用程序使用此功能的性能改进进行了一些测量:

http://ylan.segal-family.com/blog/2012/08/27/deploy-to-heroku-with-near-zero-downtime/

于 2012-08-27T17:08:20.033 回答
8

您可能会对他们称为preboot的功能感兴趣。

取自他们的文档:

此功能通过在终止现有 Web dyno 之前使用新代码启动 Web dyno 来提供无缝部署。

某些应用程序需要很长时间才能启动,这可能会导致在部署期间服务 HTTP 请求时出现不可接受的延迟。

有几个注意事项:

  • 您必须至少有两个网络测功机才能使用此功能。如果您将 Web 进程类型缩放为 1 或 0,则预引导将被禁用。
  • 在新代码开始服务用户请求之前,进行部署的人必须等待几分钟;这比没有预引导的情况发生得晚(但与此同时,旧的测功机仍会及时处理用户请求)。
  • 将有一小段时间(一两分钟) heroku ps 显示新代码的状态,但旧代码仍在处理用户请求。

有关它的更多信息,请参阅他们的文档

于 2012-10-15T11:14:43.033 回答
2

否 - 目前在 Heroku cedar 上使用 Unicorn 是不可能的。几个星期以来,我一直在烦扰 Heroku。

这是 Heroku 支持在 2012 年 3 月 8 日对我的电子邮件的回复:

嗨,您可以在进行部署时启用维护模式,至少您的用户会看到维护页面而不是错误,并且请求队列也不会建立。

我们绝对意识到这是一种痛苦,我们正在努力在未来提供滚动/零停机部署。不过,我们没有 ETA 可宣布。

于 2012-04-04T15:58:37.263 回答
2

这是可能的,但需要大量的前瞻性计划。从 Rails 3.1 开始,需要执行三个任务

  • 上传新代码
  • 运行任何数据库迁移
  • 同步资产

上传代码并重新启动相当简单,主要问题在于其他两个,但绕过它们的方式几乎相同。

基本上你需要:

  • 使代码与您需要运行的迁移兼容
  • 运行迁移,并删除专门为其编写的任何代码

例如,如果你想删除一个列,你需要部署一个补丁告诉 ActiveRecord 先忽略它。只有这样,您才能部署迁移并清理该补丁。

简而言之,您需要考虑您的数据库和代码兼容性以解决它们,以便两者在版本控制方面可以重叠。

此方法的替代方法可能是同时在 Heroku 上运行两个版本的应用程序。部署时,将域切换到其他版本,进行部署,然后再次切换回来。这在大多数情况下会有所帮助,但同样,数据库兼容性也是一个问题。

就个人而言,我会说,如果您的部署很重要,需要这种考虑,那么将应用程序的一部分脱机可能是最安全的答案。通过将一个应用程序分解为几个较小的应用程序可以帮助缓解这种情况,这是我经常使用的一种机制。

于 2011-12-05T23:12:02.633 回答