如何在docker容器中优雅地关闭tomcat中的servelts?

ymzxtsji  于 2024-01-08  发布在  Docker
关注(0)|答案(2)|浏览(295)

到目前为止,我发现:

  • “docker stop”向容器中的进程ID 1发送SIGTERM。
  • 容器中的进程ID 1是运行tomcat的java进程。*)
  • 是的,tomcat本身会优雅地关闭,但servlet不会。
  • Servlet在2秒后被杀死,即使它们正在处理请求(!!)
  • )旁注:虽然我们的容器入口是[“/opt/tomcat/bin/catalina.sh“,“run”],但在catalina.sh中,java进程是通过bash buildin“exec”命令启动的,因此java进程 * 替换 * 了shell进程,从而成为新的进程id 1。(我可以通过exec到运行容器中验证这一点,并在那里执行“ps aux”。)顺便说一句,我使用的是tomcat 7.0.88。

我发现了tomcat在默认情况下会完全关闭的声明(http://tomcat.10.x6.nabble.com/Graceful-Shutdown-td5020523.html-“任何正在进行的连接都会完成”),但我所能看到的是,从docker发送到java进程的SIGTERM几乎不会停止正在进行的请求执行。
我写了一个小的rest servlet来测试这个行为:

  1. import javax.ws.rs.*;
  2. import javax.ws.rs.core.*;
  3. import javax.ws.rs.core.Response.Status;
  4. @Path("/")
  5. public class SlowServerRes
  6. {
  7. @GET
  8. @Produces(MediaType.TEXT_PLAIN)
  9. @Path("test1")
  10. public Response test1(@QueryParam("sleep") final int sleepDurationSec)
  11. {
  12. long received = System.currentTimeMillis();
  13. System.out.println("+++++++++++++++++++++ received request at " + received);
  14. for (int i=1; i <= sleepDurationSec; i++) {
  15. System.out.println(" ++++ Sleeping for 1 sec ("+i+")");
  16. try { Thread.sleep(1000); }
  17. catch (InterruptedException e) {
  18. System.out.println(" Sleep was interrupted at second " + i + " ... ignoring/continue sleeping.");
  19. }
  20. }
  21. long finished = System.currentTimeMillis();
  22. String result = "received: " + received + " finished: " + finished;
  23. System.out.println("+++++++++++++++++++++ " + result);
  24. Response response = Response.status(Status.OK).entity(result).build();
  25. return response;
  26. }
  27. }

字符串
经过密集的谷歌搜索,我终于看到了这个帖子:http://grokbase.com/t/tomcat/users/113nayv5kx/tomcat-6-graceful-shutdown
所以给tomcat的宽限期不会作为servlet的宽限期传播。我想知道这是否有意义,但看起来这是事实。所以让servlet正确结束正在进行的请求的唯一方法是改变“unloadDelay”(https://tomcat.apache.org/tomcat-7.0-doc/config/context.html)。
但是,我没有在tomcat配置文件中找到合适的位置来定义非默认的unloadDelay。如果这很重要,我主要关心的是jersey servlet(org.glassfish.jersey.servlet.ServletContainer)。
或者还有其他可能性,我现在还没发现?
(我将kubernetes添加到标签列表中,因为这可能是Kubernetes的主要关注点,因为它经常重新定位(docker stop->SIGTERM)容器,只是为了保持负载平衡。

ctzwtxfj

ctzwtxfj1#

现在我在这里找到了答案:https://stackoverflow.com/a/11154770/2081279
它在Linux下工作,

  1. <Context path="/myapp" unloadDelay="10000"/>

字符串
但仅在文本中具有大写字母“C“。

disbfnqx

disbfnqx2#

您可以公开一个REST API来正常停止服务器。
1.实现并使用javax过滤器,该过滤器将进程中的HTTP请求保持在自己的状态。
1.当停止事件发生时,当前的tomcat示例不再需要处理任何新的客户端请求,因此要确保新的请求不会被重定向到此示例。
1.当停止事件发生时(第二件事),启动一个线程,等待所有请求被处理。当所有响应被发送时,请求tomcat示例关闭:the command String shutdown may be a way

相关问题