加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

SIGTERM没有被java进程使用’docker stop’和官方java图像接收

发布时间:2020-12-14 05:33:26 所属栏目:Java 来源:网络整理
导读:我使用基于debian / jessie的图像 java:7u79在Docker容器中运行dropwizard Java应用程序. 我的Java应用程序处理SIGTERM信号正常关闭.当我运行没有Docker的应用程序时,SIGTERM处理功能非常完美. 当我在Docker容器中运行它时,当我发出docker stop命令时,SIGTE
我使用基于debian / jessie的图像 java:7u79在Docker容器中运行dropwizard Java应用程序.

我的Java应用程序处理SIGTERM信号正常关闭.当我运行没有Docker的应用程序时,SIGTERM处理功能非常完美.

当我在Docker容器中运行它时,当我发出docker stop命令时,SIGTERM不会到达Java应用程序. 10秒钟后,它会突然死亡.

我的Docker文件:

FROM java:7u79

COPY dropwizard-example-1.0.0.jar /opt/dropwizard/
COPY example.keystore /opt/dropwizard/
COPY example.yml /opt/dropwizard/

WORKDIR /opt/dropwizard

RUN java -jar dropwizard-example-1.0.0.jar db migrate /opt/dropwizard/example.yml

CMD java -jar dropwizard-example-1.0.0.jar server /opt/dropwizard/example.yml

EXPOSE 8080 8081

这个Docker文件有什么问题?有什么办法可以解决这个问题吗?

解决方法

假设您通过在Dockerfile中定义以下内容来启动Java服务:
CMD java -jar ...

当您现在输入容器并列出过程通过docker exec -it< containerName> ps AHf(我没有尝试使用java但是使用ubuntu映像)你看到你的Java进程不是根进程(不是PID 1的进程),而是/ bin / sh进程的子进程:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:27 ?        00:00:00 /bin/sh -c java -jar ...
root         8     1  0 18:27 ?        00:00:00   java -jar ...

所以基本上你有一个Linux shell,它是PID 1的主要过程,它具有带有PID 8的子进程(Java).

要使信号处理正常工作,您应该避免这些shell父进程.这可以通过使用内置shell命令exec来完成.这将使子进程接管父进程.所以最后,前一个父进程不再存在了.并且子进程成为PID 1的过程.请在Dockerfile中尝试以下操作:

CMD exec java -jar ...

过程列表应该显示如下:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:30 ?        00:00:00 java -jar ...

现在你只有一个进程与PID 1.一般来说,一个很好的做法是使docker容器只包含一个进程 – 一个PID 1(或者如果你真的需要更多的进程,那么你应该使用例如supervisord作为PID 1,它本身采取照顾其子进程的信号处理).

使用该设置,SIGTERM将被Java进程直接处理.没有任何shell进程之间可能会中断信号处理.

编辑:

通过使用不同的CMD语法来隐含地实现同样的执行效果(感谢Andy的评论):

CMD ["java","-jar","..."]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读