首页 > 解决方案 > 如何解决 OpenShift 集群中多个 pod 中的 liquibase 等待更改日志锁定问题?

问题描述

我们支持使用 Spring Boot 用 Ja​​va 编写并部署在 OpenShift 中的多个微服务。一些微服务与数据库通信。我们经常在单个部署中的多个 pod 中运行单个微服务。当每个微服务启动时,它会启动 liquibase,它会尝试更新数据库。问题是有时一个 pod 在等待更新日志锁定时失败。当在我们的生产 OpenShift 集群中发生这种情况时,我们预计其他 pod 在重新启动时会失败,因为与更改日志锁定问题相同。因此,在最坏的情况下,所有 pod 都将等待解除锁定。

我们希望 Liquidbase 在每个 pod 启动时自动准备我们的数据库模式。

将此逻辑存储在每个微服务中是否很好?当出现liquidbase changelog lock问题时,我们如何自动解决问题?我们是否需要将数据库准备逻辑放在单独的部署中?

所以也许我应该解释我的问题。就微服务架构而言,运行数据库迁移的最佳方式是什么?也许我们不应该在每个 pod 中使用 db 迁移?也许最好通过单独的部署来完成它,或者用一些额外的 Jenkins 工作来完成,而不是在 OpenShift 中?

标签: databasespring-bootkubernetesopenshiftliquibase

解决方案


我们将 liquibase 迁移作为 Kubernetes 中的初始化容器运行。在微服务中运行 Liquibase 的问题是,如果在配置的超时之前准备就绪探测不成功,Kubernetes 将终止 pod。在我们的案例中,这有时会发生在大型数据库迁移期间,这可能需要几分钟才能完成。Kubernetes 将终止 pod,使 DATABASECHANGELOGLOCK 处于锁定状态。使用 init-containers 不会有这个问题。有关详细说明,请参见https://www.liquibase.org/blog/using-liquibase-in-kubernetes

更新 请看一下这个 Liquibase 扩展,它通过使用数据库锁替换了 StandardLockService:https ://github.com/blagerweij/liquibase-sessionlock

此扩展使用 MySQL 或 Postgres 用户锁定语句,这些语句在数据库连接关闭时自动释放(例如,当容器意外停止时)。使用扩展唯一需要做的就是向库中添加一个依赖项。Liquibase 将自动检测改进的 LockService。

我不是图书馆的作者,但我在寻找解决方案时偶然发现了图书馆。我通过将库发布到 Maven 中心来帮助作者。目前支持 MySQL 和 PostgreSQL,但应该很容易支持其他 RDBMS。


推荐阅读