到目前为止我发现了什么:
- “docker stop”向容器中的进程 ID 1 发送 SIGTERM。
- 容器中的进程ID 1是运行tomcat的java进程。*)
- 是的,tomcat 本身会正常关闭,但 servlet 不会这样做。
- Servlet 会在 2 秒后被终止,即使它们正在处理请求(!!)
*) 边注:
虽然我们的容器入口点是[ "/opt/tomcat/bin/catalina.sh", "run" ],但是
在catalina.sh中,java进程是通过bash内置的“exec”命令启动的,
因此java进程replacesshell 进程因此成为新的进程 id 1。
(我可以通过 exec 进入正在运行的容器并在其中执行“ps aux”来验证这一点。)
顺便说一句,我使用的是 tomcat 7.0.88。
我发现有关 tomcat 默认情况下正常关闭的声明(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 能够正确结束其正在进行的请求的唯一方法是更改
“卸载延迟”(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)容器,只是为了保持负载平衡。)
现在我在这里找到了答案:https://stackoverflow.com/a/11154770/2081279
它在linux下对我有用
<Context path="/myapp" unloadDelay="10000"/>
但仅限于大写字母“Context.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)