持续部署和数据库迁移

时间:2018-08-19 00:46:42

标签: symfony yii continuous-integration migration continuous-deployment

这个问题就像“首先是鸡肉还是鸡蛋?”。

假设我们有一些源代码。使用symfony或yii编写。它具有数据库迁移代码,需要对数据库进行一些更改。

现在,我们有一些提交可以更新我们的代码(例如,新类)和一些数据库更改(可以更改旧列或添加新表)。

当我们在本地主机上进行开发或更新开发服务器时,可以有时间停止服务\任何操作并更新服务器。但是,当我们尝试在生产服务器上执行此操作时,将使所有内容崩溃一会儿,而这不是一个选择。

为什么会发生这种情况-当我们将其拉出(git \ mercurial)时,我们的代码将被更新,但不是数据库,并且将在执行代码时被更新-它将引发数据库异常。要修复它,我们应该运行内置框架迁移。因此,最终我们的服务器将崩溃,直到调用迁移为止。

代码和迁移应“一次​​性”更新。

处理该问题的最佳做法是什么?

已添加: 诸如“先拉后运行迁移”之类的解决方案-在高负载项目中不是一种选择。因为即使是在一秒钟的高负载下,某些条目\呼叫也可能会变得无聊。

我们也不能停止服务器。

2 个答案:

答案 0 :(得分:2)

启动零停机时间部署可能有些棘手,并且有很多方法可以实现这一目标。

对于数据库,建议以向后兼容的方式进行更改。因此,例如添加可为空的列或新表不会影响您现有的代码库,并且可以安全地完成。因此,如果您想添加一个新的不可为空的列,则需要3个步骤:

  1. 将新列添加为可空
  2. 填充数据以确保没有空值
  3. 使列NOT NULL

您至少需要为1和3进行新的部署。在修改列时,几乎是一样的,您创建一个新列,转移数据,释放使用该新列的代码(可选地,使用旧列作为后备),然后删除其中的旧列(以及后备代码)。第三次部署。

这样,您可以确保数据库更改不会导致现有应用程序停机。这需要格外小心,并且显然需要您具有良好的部署管道以允许快速发布。如果要花费数小时才能发布,则此方法将很有趣。

您可以复制数据库(甚至整个系统),进行迁移,然后切换到该实例,但是在大多数应用程序中,这是不可行的,因为要使两个实例在部署之间保持同步会很麻烦。我不建议为此花太多时间,但是我可能会因经验而有所偏差。

如果要用较新的代码切换当前代码版本,则有多种选择。像kubernetes这样基于花式云的解决方案使这种操作变得容易。使用新版本创建第二个群集,然后将流量从旧群集缓慢路由到新群集。如果只有一台服务器,通常将新发行版部署到单独的文件夹中,执行所有管理任务,例如预热缓存,然后在准备好使用该发行版时,将符号链接切换到最新发行版。如果您确实希望停机时间为零,则这两种方法都需要进行仔细的计划和调整。各种各样的事情都可能导致问题,例如共享缓存被意外清除为会话,而会话没有正确地转移到新版本中。每当会话中存储的某些内容发生更改时,您都必须采取与数据库类似的方法,并且在运行代码时或将后备状态仍然处理旧数据时,将状态缓慢转移到新状态,否则在执行以下操作时可能会出错阅读会话,为您的客户带来500页。

在尽可能减少中断和故障的情况下进行部署的关键是对系统和应用程序进行良好的监控,以查看部署过程中出现问题的地方,从而使其在一段时间内变得更加稳定。

答案 1 :(得分:1)

您可以创建一个备份服务器,其内容与您当前的服务器相同。然后执行一些错误检测。 如果在主服务器上检测到错误,请更新DNS记录以将流量转移到辅助服务器。 一旦主数据库备份并开始运行,流量就会移回到主数据库,然后在辅助数据库中同步更改。 这些称为故障转移服务器。