最近在研究通过Docker部署Java应用,遇到了许多问题。今天说的是其中遇到的一个问题——实现Java应用优雅停机(shutdown gracefully)。
很多时候,我们的Java应用在关闭前需要做一些业务处理(比如通知、资源清理等)。在Java中我们可以通过监听进程关闭的SIGTERM信号来实现优雅关机。但通过Docker启动Java进程,无论是通过docker stop 还是 docker kill来关闭docker进程,Java应用都无法接受到SIGTERM信号。下面是我的DOCKERFILE
FROM java:8 VOLUME /tmp RUN mkdir /app ADD app_0.1.jar /app/app.jar ADD runboot.sh /app/ RUN bash -c 'touch /app/app.jar' WORKDIR /app RUN chmod a+x runboot.sh CMD /app/runboot.shrunboot.sh脚本
#!/bin/bash java -Djava.security.egd=file:/dev/./urandom \ -jar /app/app.jar于是进入docker容器查看了下进程,发现docker会先启动一个shell进程,然后java进程作为该shell进程的子进程执行。因此java进程就无法接受到SIGTERM信号,如图:
那就直接舍弃runboot.sh,直接CMD执行java命令试试。Dockerfile
FROM java:8 VOLUME /tmp RUN mkdir /app ADD app_0.1.jar /app/app.jar RUN bash -c 'touch /app/app.jar' WORKDIR /app CMD exec java -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar果然就OK了。