Azure部署插槽和数据库迁移

Cai*_*ard 13 azure azure-web-app-service

TLDR:

如何在临时插槽中运行的应用程序知道它是否正在升级并连接到测试数据库上的测试数据库/运行迁移?而且,临时插槽中的同一个应用程序如何自动意识到它已被交换到实时生产槽并且现在负责实时业务操作?(因此它可以切换到使用实时数据库,迁移实时数据库等)

长版:

该主题部分由以下问题涵盖:Azure Web App部署插槽,具有数据库迁移功能

但我没有真正得到我的答案..

我的应用程序使用FluentMigrator,在应用程序初始化时由事件/代码启动,以运行数据库迁移.MSBuild曾经这样做,但现在我很确定它是以编程方式调用的

似乎最明智的是:

  • 生产有一个基于插槽的应用程序设置,指向生产数据库中的代码
  • 暂存以具有基于插槽的应用程序设置,该设置将代码指向登台数据库

如果登台具有破坏数据库以便生产理解的迁移,我看不到任何其他方式让生产保持功能,同时正在证明分段; 两个DB必须分开

因此,如果数据库是分开的,那么切换世界到使用暂存槽中的代码的唯一(几乎)零停机方式是,如果交换机导致应用程序重新初始化并更改它以使其变为指向生产数据库,然后fluentmigrator(也应该再次调用)可以将同一组迁移应用于生产,并且staging中的代码在生产数据库上运行一段时间的业务.

..production codebase已更新,并且发生了回调.生产代码永远不会迁移生产数据库,因为在生产中的新版本启动时,它已经由暂存代码更新

我预见到的事情唯一的另一种方法是拥有两个DB,两个插槽,而且你永远不会执行交换; 您只需部署到暂存,它会更新暂存数据库,您进行测试并证明是好的,您部署到生产中,它会更新产品数据库,验证应用程序正在运行......并且世界在生产时遭受了少量的停机时间(如果构建失败,则为主要数量)

前者有机制吗?当交换发生时,应用程序如何指向新数据库以及如何再次运行迁移?

如果后者是唯一的方式,那么部署插槽也可能只是另一个Web应用程序,对吧?用于登台的Web应用程序和用于prod的Web应用程序,以减轻任何混淆槽因为它们在门户中的表示方式而导致.

Coc*_*lla 17

可以通过暂存和生产Azure App Service插槽共享单个生产数据库,并且仍然可以实现零停机时间部署.

为此,您需要确保所有迁移都向后兼容,以便Web应用程序的当前版本和新版本可以与同一数据库同时运行.这意味着您可以部署到暂存插槽,对生产数据库执行冒烟测试,然后交换生产槽的暂存插槽.

允许此工作的一些规则:

  • 新列应该可以为空或设置默认值
  • 列不能删除
  • 列无法重命名

当您确实需要进行破坏性更改(例如删除列)时,您需要有2个版本:

  1. 从Web应用程序中删除依赖关系的版本
  2. 一个执行数据库模式更改的发行版

这听起来像是痛苦,但在实践中,你可能不会发现自己经常进行破坏性的改变.

  • @AdrianNasui 我不使用 EF 迁移,因为它们没有提供足够的控制(例如对于这样的事情),而是支持基于 SQL 的迁移(有什么更好的语言来描述 DB 更改?!) - 在 .NET 世界中,我像 DbUp 一样。 (2认同)

Voč*_*čko 2

我最近一直在解决类似的问题。我的情况更容易,因为我只部署到内容保存数据库,而数据收集则放在一边并且不被触及(一旦我们必须升级它们,这将是一个挑战)。

然而,我们提出了一个似乎对我们来说最好的解决方案。我们在弹性池中有两组数据库时进行插槽部署(这对它们几乎没有额外的成本),而每个插槽都指向一组数据库。当我们进行部署时,我们更新代码和与插槽相关的数据库,进行测试以验证其是否全部正常工作,然后进行交换 - 代码和数据库。这意味着交换后,部署槽中的代码上线并指向我们测试过的数据库,而之前上线的代码和数据库集并未离线,准备进行另一次部署。

我们可以承受这种安慰,因为数据库中的数据完全在我们的控制之下,因此我们可以防止在部署和交换之间写入数据库。

但是,如果您的数据库正在从实时应用程序收集数据,您可能会考虑在升级时关闭应用程序,将实时数据合并到登台数据库,升级登台数据库(其中已经包含最新数据)然后进行交换。在我看来,这是防止数据丢失的最安全方法。您还可以先迁移临时数据库,然后关闭应用程序并将数据合并到新架构中,这取决于您应用程序的特性,在不知道您的确切情况的情况下给出通用建议是相当复杂的。

希望这些想法至少对您有一点帮助,如果您找到了更好的方法,我很想听听。