【发布时间】:2019-05-01 14:36:01
【问题描述】:
我的项目正在从带有 Java 8 的 Spring Boot 2.0.4 迁移到带有 Java 11 的 Spring Boot 2.1.0。当应用程序使用 Spring Boot 2.0.4 和 Java 8 构建并在 Docker / Docker Compose 中运行时,@ 987654322@-annotated 方法被调用,但在迁移到 Spring Boot 2.1.0 和 Java 11 之后,@PreDestroy-annotated 方法不再被调用。
我已经尝试从注解切换到实现InitializingBean 和DisposableBean,如here 所述,但没有调用DisposableBean.destroy 方法。
我也尝试向 javax.annotation-api 版本 1.3.2 添加依赖项,结果相同。
如何重现:
使用生命周期 bean 创建一个最小的 Spring 应用程序:
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class Life implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("--- Life.shutdown");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("--- Life.startup");
}
}
从目标子文件夹启动 Spring 应用程序:
cd target
java -jar demo-0.0.1-SNAPSHOT.jar
当使用 Ctrl+C 停止应用程序时,会调用 DisposableBean.destroy。
返回父文件夹:
cd ..
使用 Maven 启动 Spring 应用程序:
mvn spring-boot:run
当使用 Ctrl+C 停止应用程序时,会调用 DisposableBean.destroy。
Dockerfile:
FROM openjdk:11.0.1-jre-slim
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT java -jar /app.jar
构建、运行和停止 Docker 映像:
docker build -t demo .
docker run -p 8080:8080 demo
docker ps
docker stats 3ca5b804ab13
docker stop 3ca5b804ab13
docker logs 3ca5b804ab13
当使用 docker stop 停止应用程序时,不会调用 DisposableBean.destroy。
docker-compose.yml:
demo:
image: demo
ports:
- '8080:8080'
使用 Docker Compose 运行 Docker 镜像(模拟 OpenShift):
docker-compose up
docker-compose down
demo_demo_1 exited with code 137
当使用 docker-compose down 停止应用程序时,不会调用 DisposableBean.destroy。
我怀疑 Docker 在发出 SIGKILL 之前尝试了 SIGTERM,因为在容器被杀死之前有 10 秒的延迟。
【问题讨论】:
-
有没有什么东西正在用
SIGKILL杀死JVM? -
很难在没有看到任何类型的配置文件、docker compose 文件等的情况下诊断任何东西。当你直接在金属上运行而不涉及 docker 时,你能重现这个问题吗?
标签: java spring spring-boot docker