<bdo id='EF7Uw'></bdo><ul id='EF7Uw'></ul>
      <legend id='EF7Uw'><style id='EF7Uw'><dir id='EF7Uw'><q id='EF7Uw'></q></dir></style></legend>
    1. <i id='EF7Uw'><tr id='EF7Uw'><dt id='EF7Uw'><q id='EF7Uw'><span id='EF7Uw'><b id='EF7Uw'><form id='EF7Uw'><ins id='EF7Uw'></ins><ul id='EF7Uw'></ul><sub id='EF7Uw'></sub></form><legend id='EF7Uw'></legend><bdo id='EF7Uw'><pre id='EF7Uw'><center id='EF7Uw'></center></pre></bdo></b><th id='EF7Uw'></th></span></q></dt></tr></i><div id='EF7Uw'><tfoot id='EF7Uw'></tfoot><dl id='EF7Uw'><fieldset id='EF7Uw'></fieldset></dl></div>
      <tfoot id='EF7Uw'></tfoot>

      <small id='EF7Uw'></small><noframes id='EF7Uw'>

      1. 使用'docker stop'和官方java图像的java进程没有收到SIGTERM

        SIGTERM not received by java process using #39;docker stop#39; and the official java image(使用docker stop和官方java图像的java进程没有收到SIGTERM)
      2. <i id='EM1Yq'><tr id='EM1Yq'><dt id='EM1Yq'><q id='EM1Yq'><span id='EM1Yq'><b id='EM1Yq'><form id='EM1Yq'><ins id='EM1Yq'></ins><ul id='EM1Yq'></ul><sub id='EM1Yq'></sub></form><legend id='EM1Yq'></legend><bdo id='EM1Yq'><pre id='EM1Yq'><center id='EM1Yq'></center></pre></bdo></b><th id='EM1Yq'></th></span></q></dt></tr></i><div id='EM1Yq'><tfoot id='EM1Yq'></tfoot><dl id='EM1Yq'><fieldset id='EM1Yq'></fieldset></dl></div>

        <small id='EM1Yq'></small><noframes id='EM1Yq'>

          <legend id='EM1Yq'><style id='EM1Yq'><dir id='EM1Yq'><q id='EM1Yq'></q></dir></style></legend>
            <tbody id='EM1Yq'></tbody>
          • <tfoot id='EM1Yq'></tfoot>

            • <bdo id='EM1Yq'></bdo><ul id='EM1Yq'></ul>

                  本文介绍了使用'docker stop'和官方java图像的java进程没有收到SIGTERM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在使用基于 debian/jessie 的图像 java:7u79 在 Docker 容器中运行 dropwizard Java 应用程序.

                  I am running a dropwizard Java application in a Docker container using the image java:7u79 based on debian/jessie.

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

                  My Java application handles the SIGTERM signal to shutdown gracefully. The SIGTERM handling works perfect when I run the application without Docker.

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

                  When I run it in a Docker container the SIGTERM does not reach the Java application when I issue a docker stop command. It kills the process abruptly after 10 seconds.

                  我的Dockerfile:

                  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
                  

                  这个 Dockerfile 有什么问题?有没有其他方法可以解决这个问题?

                  What is wrong with this Dockerfile? Is there any other way to tackle this problem?

                  推荐答案

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

                  Assuming you launch a Java service by defining the following in your Dockerfile:

                  CMD java -jar ...
                  

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

                  When you now enter the container and list the processes e.g. by docker exec -it <containerName> ps AHf (I did not try that with the java but with the ubuntu image) you see that your Java process is not the root process (not the process with PID 1) but a child process of a /bin/sh process:

                  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).

                  So basically you have a Linux shell that is the main process with PID 1 which has a child process (Java) with PID 8.

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

                  To get signal handling working properly you should avoid those shell parent process. That can be done by using the builtin shell command exec. That will make the child process taking over the parent process. So at the end the former parent process does not exist any more. And the child process becomes the process with the PID 1. Try the following in your Dockerfile:

                  CMD exec java -jar ...
                  

                  然后进程列表应该显示如下:

                  The process listing then should show something like:

                  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,它自己负责子进程的信号处理).

                  Now you only have that one process with PID 1. Generally a good practice is to have docker containers only contain one process - the one with PID 1 (or if you really need more processes then you should use e.g. supervisord as PID 1 which itself takes care of signal handling for its child processes).

                  通过该设置,Java 进程将直接处理 SIGTERM.中间没有任何 shell 进程可以中断信号处理.

                  With that setup the SIGTERM will be treated directly by the Java process. There is no shell process any more in between which could break signal handling.

                  编辑:

                  同样的 exec 效果可以通过使用不同的 CMD 语法来实现(感谢 Andy 发表评论):

                  The same exec effect could be achieved by using a different CMD syntax that does it implicitly (thanks to Andy for his comment):

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

                  这篇关于使用'docker stop'和官方java图像的java进程没有收到SIGTERM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How can I detect integer overflow on 32 bits int?(如何检测 32 位 int 上的整数溢出?)
                  Local variables before return statements, does it matter?(return 语句之前的局部变量,这有关系吗?)
                  How to convert Integer to int?(如何将整数转换为整数?)
                  How do I create an int array with randomly shuffled numbers in a given range(如何在给定范围内创建一个随机打乱数字的 int 数组)
                  Inconsistent behavior on java#39;s ==(java的行为不一致==)
                  Why is Java able to store 0xff000000 as an int?(为什么 Java 能够将 0xff000000 存储为 int?)
                  <legend id='dKKWU'><style id='dKKWU'><dir id='dKKWU'><q id='dKKWU'></q></dir></style></legend>
                    <tbody id='dKKWU'></tbody>

                        <small id='dKKWU'></small><noframes id='dKKWU'>

                          <bdo id='dKKWU'></bdo><ul id='dKKWU'></ul>

                          • <i id='dKKWU'><tr id='dKKWU'><dt id='dKKWU'><q id='dKKWU'><span id='dKKWU'><b id='dKKWU'><form id='dKKWU'><ins id='dKKWU'></ins><ul id='dKKWU'></ul><sub id='dKKWU'></sub></form><legend id='dKKWU'></legend><bdo id='dKKWU'><pre id='dKKWU'><center id='dKKWU'></center></pre></bdo></b><th id='dKKWU'></th></span></q></dt></tr></i><div id='dKKWU'><tfoot id='dKKWU'></tfoot><dl id='dKKWU'><fieldset id='dKKWU'></fieldset></dl></div>
                          • <tfoot id='dKKWU'></tfoot>