[英]Bean lifecycle in Spring Boot 2.1 and Java 11
我的項目正在從使用Java 8的Spring Boot 2.0.4遷移到使用Java 11的Spring Boot 2.1.0。當應用程序使用Spring Boot 2.0.4和Java 8構建並在Docker / Docker Compose中運行時,@ @PostConstruct
-annotated方法被調用,但在轉移到Spring Boot 2.1.0和Java 11之后,不再調用@PreDestroy
-annotated方法。
我試圖從注釋切換到實施InitializingBean
和DisposableBean
描述在這里 ,但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。
泊塢窗,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秒的延遲。
有很多地方設置可能出錯。 首先,我建議確定java / spring部分是否存在某些問題,或者是與docker / environment相關的問題。 從這個問題看起來它與java有關,但實際上我懷疑它不是在java / spring中。
所以, mvn spring-boot:run
按預期工作,我看到你將spring boot應用程序打包為jar(app.jar)可能帶有spring boot插件。 這也是一個可能出錯的地方,因為spring boot使用特殊的類加載器來加載運行時的東西。
因此,為了完全消除“java / spring”部分導航到target
目錄並運行java -jar app.jar
(確保本地機器上安裝了java 11)。 如果它不起作用 - 調查java / spring部分,否則繼續使用docker部分。
應用程序可能會按預期工作。
現在,至於docker設置。 運行docker compose並看到它失敗后,
您可以使用以下命令:
docker ps -a // -a flag to see container ids of containers that were stopped for whatever reason as well.
現在,找到退出的java進程的Id並檢查其日志:
docker logs <ID_OF_THE_EXTED_CONTAINER_GOES_HERE>
現在很可能是應用程序上下文無法啟動(可能是與網絡相關的問題或其他問題,這里很難說沒有看到實際的日志),因此也就是問題。
另一個可能的問題是應用程序“太重”(我的意思是它超過了對docker容器施加的一些配額)。
您可以運行docker stats <CONTAINER_ID>
命令以實時查看其內存/ CPU使用情況,或從應用程序中收集指標。
我想我找到了解決方案(在這個博客條目中 ):在Dockerfile中使用exec表單而不是shell表單,這樣Docker發出的SIGTERM就會遇到java進程而不是bash進程(它不會將信號轉發給任何子進程) )。
ENTRYPOINT java -jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.