Azure部署插槽和数据库迁移

时间:2017-06-28 17:32:17

标签: azure azure-web-app-service

TLDR:

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

长版:

这个问题部分涉及这个问题:Azure Web App deployment slots with database migration

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

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

似乎最明智的是:

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

如果升级具有破坏数据库以便生产理解的迁移,我无法看到任何其他方式让生产保持正常运行,同时升级已经过验证;两个DB必须分开

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

..更新生产代码库并进行交换。生产代码永远不会迁移生产数据库,因为在生产中的新版本启动时,临时代码已经更新了生产代码

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

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

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

2 个答案:

答案 0 :(得分:13)

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

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

允许此功能的一些规则:

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

如果您确实需要进行破坏性更改(例如删除列),则需要发布2个版本:

  1. 从Web应用程序中删除依赖关系的版本
  2. 执行数据库架构更改的版本
  3. 这听起来像是一种痛苦,但在实践中,你可能不会发现自己经常发生破坏性的变化。

答案 1 :(得分:2)

我最近一直在解决类似的问题。我的情况更容易,我只是部署到持有数据库的内容,而数据收集站在一边而没有被触及(一旦我们必须升级它们将具有挑战性。)

但是,我们想出了一个似乎是我们最好的解决方案。我们进行插槽部署,同时在弹性池中有两组dbs(几乎没有任何额外成本),而每个插槽指向一组dbs。 当我们进行部署时,我们更新代码和插槽相关的数据库,进行测试以验证它是否全部工作,然后进行交换 - 代码和数据库。这意味着在交换之后,部署槽中的代码会生效并指向我们测试过的dbs,而之前的实时代码和数据库集不会脱机,可以进行其他部署。

我们可以提供这种安慰,因为dbs中的数据完全在我们的控制之下,因此我们可以阻止在部署和交换之间编写数据库。

但是,如果您的数据库正在从实时应用程序收集数据,您可能会考虑在升级时关闭应用程序,将实时数据合并到暂存数据库,升级暂存数据库(已包含最新数据)然后进行交换。在我看来,这是防止数据丢失最安全的方法。您还可以先迁移暂存数据库,然后关闭应用程序并将数据合并到新模式中,这取决于应用程序的特性,而不知道您的确切情况,在此处提供通用建议非常复杂。

希望这些想法至少对你有所帮助,如果你已经找到了一些更好的方法,我很想听听它。