当前在容器化环境(ECS)中运行SpringBoot应用程序,并且我观察到了以下情况:容器在启动过程中终止,而它仍然保持Liquibase changelock。
这会导致所有随后旋转的容器出现问题,最终需要人工干预。
是否可以确保如果进程收到SIGTERM,它将正常处理终止并释放锁?
我已经确保通过InitProcessEnabled(在CloudFormation模板中)启用容器并使用“ exec java ...”作为我们使用的Java代理在这种情况下正常关闭,从而确保容器正在接收信号。
答案 0 :(得分:0)
Heyo,
正如GitHub问题中所述,我有一个解决方法。解决方案尚未实现。
您可以在运行spring boot之前手动注册一个关闭钩子。该钩子应确保终止终止,直到完成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);
}
}
还有挂钩:
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;
}
}
}
}
}
}
}
}