gpt4 book ai didi

java - 确保 spring boot 和 liquibase 接收和处理 SIGTERM

转载 作者:行者123 更新时间:2023-12-02 17:49:26 24 4
gpt4 key购买 nike

目前在容器化环境 (ECS) 中运行 SpringBoot 应用程序,我观察到容器在启动期间终止并且仍持有 Liquibase 变更锁的情况。

这会导致之后旋转的所有容器出现问题,最终需要人工干预。

是否可以确保如果进程收到 SIGTERM,它将优雅地处理终止并释放锁?

我已经通过 InitProcessEnabled(在 CloudFormation 模板中)启用并使用“exec java ...”作为我们使用的 java 代理来确保容器正在接收信号,并在这种情况下正常关闭。

最佳答案

嘿嘿,
正如 GitHub 问题中提到的,我有一个解决方法。尚未实现解决方案。
您可以在运行 spring boot 之前手动注册一个关闭 Hook 。该 Hook 应确保终止被推迟,直到 liquibase 完成。

package dang;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;


@EnableJpaRepositories
@SpringBootApplication
public class DangApplication {
public static void main(String[] args) throws InterruptedException {
Thread thread = new GracefulShutdownHook();
Runtime.getRuntime().addShutdownHook(thread);

new SpringApplicationBuilder(DangApplication.class)
.registerShutdownHook(true)
.logStartupInfo(true)
.build()
.run();
Runtime.getRuntime().removeShutdownHook(thread);
}
}

还有钩子(Hook):
package dang;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
public class GracefulShutdownHook extends Thread {
@SneakyThrows
@Override
public void run() {


super.run();
log.info("Shutdown Signal received.. Searching for Liquibase instances!");
boolean liquibaseIsRunning = true;
while (liquibaseIsRunning) {

Map<Thread,StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
for(Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {
StackTraceElement[] stackTraceElements = entry.getValue();
for (StackTraceElement stackTraceElement : stackTraceElements) {
if (stackTraceElement.getClassName().contains("liquibase") && stackTraceElement.getMethodName().contains("update")) {
try {
log.warn("Liquibase is currently updating");
entry.getKey().join();
liquibaseIsRunning = false;
} catch (InterruptedException e) {
log.error("Shutdown Hook was interrupted.. Fatal databaselock may be imminent", e);
if (Thread.interrupted()) {
throw e;
}
}
}
}
}
}
}
}
编辑
在实现我的解决方法后,liquibase 的贡献者共享了一个不同的解决方案(它实际上是通过 Spring 功能实现的相同解决方案),这比我所做的要好得多:
package dang;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;


@EnableJpaRepositories
@SpringBootApplication
public class DangApplication {
public static void main(String[] args) throws InterruptedException {
new SpringApplicationBuilder(DangApplication.class)
.initializers(ConfigurableApplicationContext::registerShutdownHook) // Registers application hook before liquibase executes.
.logStartupInfo(true)
.build()
.run();
}
}

关于java - 确保 spring boot 和 liquibase 接收和处理 SIGTERM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55954588/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com