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

2023-12-10

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

  • “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(使用前将#替换为@)

如何在docker容器中优雅地关闭tomcat中的servlts? 的相关文章

随机推荐

  • 如何在 C# 中无需更多实例即可实现登录表单和主表单

    我在单击登录按钮时创建主表单的实例 并在单击注销按钮时再次创建登录表单的实例 我的代码是 if txtUsrNm Text Admin txtPswd Text Admin mainForm mainFm new mainForm main
  • 如何在文本下显示图像作为背景?

    我想在文本下显示图像 我用 Photoshop 完成了这个 但它是一个图像 所以每次文本更改时我都必须在 Photoshop 中进行更改 我想使用 jQuery 或 CSS3 或任何其他网络技术来实现相同的目标 我想要与此类似 但不是每次文
  • python argparse 可选参数的默认值

    usage h foo FOO bar 如何确保 FOO 的默认值是abc如果我像下面一样执行我的脚本 myscript py foo bar gt bar这里是位置参数 但args foo正在考虑bar作为论点 foo 我想args fo
  • 使用一种上下文更新一个实体,并使用另一种上下文插入新实体?

    问候并感谢您阅读我的帖子 我正在使用中更新条目 照片 using context new PhotoEntities context Entry photo State EntityState Modified 问题是当我使用保存此条目时
  • 如何让 ggplot ecdf 绘制填充背景

    我试图让我的经验累积密度曲线填充它们的背景 但似乎无法实现 我尝试了以下两种方法 第一种方法似乎改变了曲线的 alpha 而不是填充 ggplot myDataFrame aes x myVariable fill myFactor geo
  • Dreamweaver CS5.5 中的 Phonegap

    版本是什么Phonegap被使用过Dreamweaver CS5 5 我尝试过替换默认的phonegap js最新版本的文件给出了错误 更换现有的是个好主意吗phonegap js最新版本的文件 升级adobe dreamweaver cs
  • Mongo 查找数组包含给定数组的 x 值的文档

    我有一个收藏 其中有类似的文件 实体字段并不是在每个文档中都设置的 并且具有不同的值 id ObjectId 5388cfbdec82ba7cd5438635 name Name1 entity Entity1 Entity2 Entity
  • Flask-sqlalchemy 中多对多多...关系的多辅助表

    许多问题都是关于多对多的问题 可以使用辅助表来解决 但是多 多 多怎么样 如果存在一种更优雅的方法来处理这个问题 我试图提出一个问题https github com pallets flask sqlalchemy issues 710 但
  • Python 多个 telnet 会话

    我需要构建一个脚本来获取尽可能多的主机的 telnet 输出 并将它们保存到每个主机的单独文件中 该脚本应作为守护进程运行 目前我有一个函数封装了为单个主机执行此操作的逻辑telnetlib 但我不知道如何进行 我计划打开一个进程 mult
  • Symfony2+Doctrine:如何将 iso8859-1 转换为 utf-8,反之亦然?

    我们正在构建一个使用 Oracle 数据库的 Symfony2 应用程序 DB中的所有数据编码为WE8ISO8859P15 iso 8859 1 所有网站编码为utf 8 有没有办法将从数据库接收到的所有数据转换为utf8 并将发送到数据库
  • GNU Radio:使用声音输出作为输入源

    In gnuradio 伴侣我使用音频源块作为下一个块的输入信号 一切工作几乎都很好 唯一的小问题是我从麦克风收到信号 这是正常行为 我宁愿直接播放音频信号 而不必通过我的扬声器 我房间的空气和麦克风 所有这些都会产生信号损失并增加噪声 我
  • 如何填充 MVC4 剃刀视图的下拉列表 (C#)

    用户档案模型 Table Users public class UserProfiles Key DatabaseGeneratedAttribute DatabaseGeneratedOption Identity public int
  • 使用 pyodbc 将 Python 连接到 mac 中的 Teradata

    我成功安装了 python 2 7 的 pyodbc 模块 但是 当输入以下代码连接到teradata时 import pyodbc conn pyodbc connect DRIVER Teradata DBCNAME
  • C++ 抑制自动初始化和销毁

    如何抑制类型的自动初始化和销毁 虽然这很美妙T buffer 100 自动初始化所 有元素buffer 并在它们超出范围时销毁它们 这不是我想要的行为 include
  • 从 AsyncTask 获取返回的 JSON

    所以我有这个扩展 AsyncTask 的加载器类 那我就做new loader execute 但我想用JSONArray 响应我的加载器类returns我怎么做 因为我在几个不同的地方都需要它 或者我应该将代码移至 onPostExecu
  • 如何将多个输入的行保存在数据库的同一列中?

    数据库表 id title reading writing speaking 表单 blade php table tr th Language th th Reading th th Writing th th Speaking th t
  • 使用 docker-compose 自动创建数据库和表

    我正在使用 docker compose 上传环境 但我想在 docker compose 中自动创建一个表 但是它不起作用 docker 撰写 mysql image mysql 5 7 stdin open true tty true
  • 处理 INI 文件中重复的节名称

    我需要从 INI 文件加载这些值并使用 C Boost 库在应用程序中打印它们 这些部分具有重复的名称 我被限制只能使用 C Boost 库 numColors 4 boardSize 11 numSnails 2 initializati
  • 如何在Python中确定一周的第一天

    根据区域设置 我需要找到一周的第一天 周日 周一 在JAVA中我会这样做 Calendar FR cal Calendar getInstance Locale FRANCE Calendar CA cal Calendar getInst
  • 如何在docker容器中优雅地关闭tomcat中的servlts?

    到目前为止我发现了什么 docker stop 向容器中的进程 ID 1 发送 SIGTERM 容器中的进程ID 1是运行tomcat的java进程 是的 tomcat 本身会正常关闭 但 servlet 不会这样做 Servlet 会在