我们正在支持使用Spring Boot以Java编写并部署在OpenShift中的几个微服务。一些微服务与数据库通信。我们经常在单个部署中在多个pod中运行单个微服务。当每个微服务启动时,它会启动liquibase,它会尝试更新数据库。问题是有时一个pod在等待变更日志锁时失败。当这种情况发生在我们的生产OpenShift集群中时,我们预计其他pod会在重新启动时失败,因为变更日志锁问题存在同样的问题。因此,在最坏的情况下,所有pod都会等待锁被解除。
我们希望liquidbase在每个pod启动时自动准备数据库模式。
在每个微服务中存储这种逻辑好吗?当出现liquidbase changelog锁问题时,我们如何自动解决该问题?我们需要将数据库准备逻辑放在单独的部署中吗?
所以也许我应该解释一下我的问题。从微服务架构的角度来看,运行数据库迁移的最佳方式是什么?也许我们不应该在每个pod中使用数据库迁移?也许最好通过单独的部署来完成,或者通过一些额外的Jenkins工作来完成,而不是在OpenShift中完成?
在我的公司中,我们通过遵循Liquibase建议的Init容器的相同方法来解决这个问题,但我们没有使用新的容器并通过Liquibase CLI运行Liquibase迁移,而是重用现有的Spring Boot服务设置,但只是执行Liquibase逻辑。我们创建了一个替代的主类,可以在入口点中使用它来使用Liquibase填充数据库。
InitContainerApplication类提供了启动应用程序和设置Liquibase所需的最低配置。
典型用法:
entrypoint: "java -cp /app/extras/*:/app/WEB-INF/classes:/app/WEB-INF/lib/* com.backbase.buildingblocks.auxiliaryconfig.InitContainerApplication"
给你上课
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.ApplicationContext;
@SpringBootConfiguration
@ImportAutoConfiguration(InitContainerAutoConfigurationSelector.class)
public class InitContainerApplication implements ApplicationRunner {
@Autowired
private ApplicationContext appContext;
public static void main(String[] args) {
SpringApplication.run(InitContainerApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
SpringApplication.exit(appContext, () -> 0);
}
}
以下是作为Init容器的用法:
spec:
initContainers:
- name: init-liquibase
command: ['java']
args: ['-cp', '/app/extras/*:/app/WEB-INF/classes:/app/WEB-INF/lib/*',
'com.backbase.buildingblocks.auxiliaryconfig.InitContainerApplication']
当Liquibase在spring boot应用程序部署期间启动时,它(在非常高的级别上)执行以下步骤:
因此,如果在Liquibase处于步骤1和3之间时中断应用程序部署,则数据库将保持锁定。因此,当你试图重新部署应用程序时,Liquibase会失败,因为它会将你的数据库视为锁定。
因此,在再次部署应用程序之前,您必须解锁数据库。
我知道有两个选择:
数据库天使锁
表或将锁定
设置为false
。这是DELETE VER数据库天使锁
或UPDATE数据库天使锁SET锁定=0
liquibase释放锁
命令。您可以在这里和这里找到有关它的留档。我们正在Kubernetes中作为init容器运行liquibase迁移。在微服务中运行Liquibase的问题是,如果就绪探测在配置的超时之前未成功,Kubernetes将终止pod。在我们的例子中,这种情况有时发生在大型数据库迁移期间,这可能需要几分钟才能完成。Kubernetes将终止pod,使DATABASECHANGELOGLOCK处于锁定状态。使用init容器,您将不会遇到这个问题。看见https://www.liquibase.org/blog/using-liquibase-in-kubernetes详细解释。
更新请看看这个Liquibase扩展,它使用数据库锁替换了Standard LockService:https://github.com/blagerweij/liquibase-sessionlock
该扩展使用MySQL或Postgres用户锁语句,当数据库连接关闭时(例如,当容器意外停止时),会自动释放这些语句。使用扩展只需向库中添加依赖项。Liquibase将自动检测改进的LockService。
我不是图书馆的作者,但我在寻找解决方案时偶然发现了图书馆。我通过将图书馆发布给Maven central来帮助作者。目前支持MySQL和PostgreSQL,但应该很容易支持其他RDBMS。
在这里,我试图从mongodb集合中获取最新的记录键p_id值,但得到的错误如下:SyntaxError:await仅在异步函数中有效。那么如何解决这个问题呢? 数据控制器。js:
该项目 为了寻找解决方案,我首先使用maven在执行LiquiBase:Update时将变更日志的SVN修订版存储到中。基于修订版号检索变更日志容易出错。 我已经花了一周的时间来寻找一个健壮的解决方案,在谷歌上搜索了几个小时,构建了几个测试用例(使用了适应的父级和具体的POM,部分使用了maven scm插件等等),但没有运气。最初,我计划使用LiquiBase:tag存储文件路径+修订,但只有当
我需要从其他项目模块中提取包含变更集作为maven依赖项的changelog文件。我需要在当前项目中包含其他项目的主变更日志文件(它引用了其中的所有变更集),我将在该文件中执行maven liquibase更新/回滚或spring boot liuqibase设置。有没有办法让它奏效? 但我在设置或运行LiquiBase时出错:LiquiBase.Exception.SetupException:
当前,我的中有以下内容: changelog是由Liquibase找到的,并且一切都能正常工作。 我已经将changelog和项目的所有JPA实体和存储库移到了一个单独的项目中,以便它们可以与其他项目共享。 第二个项目是第一个项目的Maven依赖项。我需要在第一个项目的中使用什么路径来访问第二个项目中的liquibase更改日志? projecta.jar->pom.xml projecta.ja
我想从src/main/resources链接yaml数据库创建规则。。在src/test/resources中,再添加一个带有示例数据的chagngelog。 src\test\resources\db\changelog\db。变更日志主机。亚马尔: 但它不起作用。所以,错误是:错误解析..//main/resources/db/changelog/db。变更日志主机。亚马尔 是否有其他选项将
在liquibase中是否有一种方法来创建java代码更改集(即提供一个java类,它将接收一个JDBC连接并在数据库中执行一些更改)? (我知道飞翔道有这样特点)