在启动容器化微服务的多个实例时处理数据库模式的创建和迁移

Posted

技术标签:

【中文标题】在启动容器化微服务的多个实例时处理数据库模式的创建和迁移【英文标题】:Handling database schema creation and migrations when launching multiple instances of a containerized microservice 【发布时间】:2017-02-02 19:36:06 【问题描述】:

我想在 docker 容器中部署我的微服务。我希望这些微服务尽可能无状态,只将状态持久化到数据库中。

这意味着有这些要求:

这些服务部署为 docker 容器,并使用 kubernetes 进行编排。 每个服务都可以部署并扩展到多个实例。 服务的每个实例都是相同的。这意味着它们都必须具有相同的环境变量和传递给它的配置。 每个实例不应该关心或知道另一个实例。 实例应该是无状态的,不应该选举领导者或有法定人数。

这导致我在处理架构创建和迁移时遇到问题:

    如果我有使用 mysql 或 Postgres 作为数据存储的服务,如何在首次启动时创建表/模式?我应该只使用CREATE IF NOT EXIST 语句并让实例在启动期间“与之抗争”吗?我无法设置环境变量来请求仅为其中 1 个实例创建表/模式。

    如何处理具有上述约束的架构迁移?有许多操作,例如删除/添加列,无法封装在事务中。

【问题讨论】:

【参考方案1】:

您需要使用能够支持数据库迁移的工具。我在 Java 领域推荐的两个是:

liquibase flyway

这些绝不是该类别中的唯一工具。他们所做的是记录已经应用到数据库实例的架构更改,确保架构与版本控制系统中捕获的所需状态相匹配。


示例

Best choice to generate scripts for different databases

【讨论】:

感谢您的链接!但是,我并不是专门寻找迁移工具的特定建议。我感兴趣的是人们在启动容器化应用程序的多个实例时如何迁移和创建数据库模式,而不必与应用程序分开管理模式。 12 因素应用程序架构文档建议像迁移这样的管理作业应该作为一次性管理进程运行12factor.net/admin-processes。话虽如此,很可能将其中一些迁移工具配置为在启动时自动运行。显然,这种解决方案是特定于技术的,这是一个 liquibase 示例:liquibase.org/documentation/servlet_listener.html liquibase 被抛弃了吗?自 2017 年 1 月以来,在 github 上有 100 多个开放的拉取请求,但没有提交到 master。Flywheel 目前似乎更加活跃。 不,liquibase 仍在积极开发中。在开发新功能时,在拉取请求上落后了一段时间,但现在赶上了【参考方案2】:

在我个人看来,数据库迁移不应该是微服务的责任。

前段时间,我阅读了很多关于蓝/绿部署和数据库迁移的信息,我们最终决定在需要时触发数据库迁移。

我现在没有链接,但它们很容易用谷歌搜索。

我提到了蓝/绿部署,因为基于微服务的方法和容器使其变得更加简单,因此如果您朝着这个方向发展,您可能应该考虑蓝/绿部署,如果您决定从容器运行迁移,这将更加困难。

您还可以考虑实施一些类似断路器的方法,以便微服务在出现数据库架构问题时停止访问数据库。

【讨论】:

以上是关于在启动容器化微服务的多个实例时处理数据库模式的创建和迁移的主要内容,如果未能解决你的问题,请参考以下文章

容器化微服务

多个实例指向同一模式的 Flyway 迁移

ASP.NET Core 6框架揭秘实例演示[05]:依赖注入基本编程模式

spring零碎知识点

Servlet 单例多线程

springmvc的DispatcherServlet在工作时是以单例模式工作的吗?