一尘不染

如何正常关闭docker容器中tomcat中的servlts?

tomcat

到目前为止,我发现了什么:

  • “ docker stop”发送SIGTERM来处理容器中的ID 1。
  • 容器中的进程ID 1是运行tomcat的Java进程。*)
  • 是的,tomcat本身会正常关闭,但servlet不会这样做。
  • Servlet会在2秒后被杀死,即使它们正在处理请求时(!!)

*)注意:尽管我们的容器入口点是[“ /opt/tomcat/bin/catalina.sh”,“ run”],但是在catalina.sh中,Java进程是通过bash buildin“ exec”命令启动的,因此java进程 替换 了shell进程,从而成为了新的进程ID1。(我可以通过exec验证它到正在运行的容器中,并在其中进行“ ps aux”。)顺便说一句,我正在使用tomcat 7.0.88。

我发现有关tomcat默认情况下执行gracefull关闭的语句(http://tomcat.10.x6.nabble.com/Graceful-
Shutdown-td5020523.html-
“任何正在进行的连接都将完成”),但是我所看到的是从docker发送到Java进程的SIGTERM导致几乎不停止正在进行的请求执行。

我编写了一个休息servlet来测试这种行为:

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;

@Path("/")
public class SlowServerRes
{
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("test1")
    public Response test1(@QueryParam("sleep") final int sleepDurationSec)
    {
        long received = System.currentTimeMillis();
        System.out.println("+++++++++++++++++++++ received request at " + received);

        for (int i=1; i <= sleepDurationSec; i++) {         
            System.out.println("  ++++ Sleeping for 1 sec ("+i+")");
            try { Thread.sleep(1000); }
            catch (InterruptedException e) { 
                System.out.println("   Sleep was interrupted at second " + i + " ... ignoring/continue sleeping."); 
            }
        }

        long finished = System.currentTimeMillis();
        String result = "received: " + received + "  finished: " + finished;
        System.out.println("+++++++++++++++++++++ " + result);
        Response response = Response.status(Status.OK).entity(result).build();
        return response;
    }
}

经过密集的谷歌搜索,我终于遇到了这个帖子: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添加到了标签列表中,因为这可能是对kubernets尤其重要的问题,因为它经常重新定位(docker stop->
SIGTERM)容器,只是为了保持负载平衡。)


阅读 558

收藏
2020-06-16

共1个答案

一尘不染

它在Linux下对我有用

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

但仅带有大写字母“ C”的文字。

2020-06-16