我正在构建一个Docker映像,该映像将启动一个运行时间较长的Java进程。我想确保它可以与容器一起杀死(例如,通过使用Ctrl + C),但仍然可以执行清理操作。
如果我在入口点使用exec java -jar
,它会按预期工作。
如果我只是执行java -jar
,则无法终止该进程。
但是exec
会使容器即使成功也退出,如果此命令不是入口点中的最后一个命令,则这是一个问题。例如,如果进行了一些文件转换或清除,将不会执行该文件:
exec java -jar "./lib/Saxon-HE-${SAXON_VER}.jar" -s:"$json_xml" -xsl:"$STYLESHEET" base-uri="$base"
rm "$json_xml"
我认为解释是,使用exec
的过程(在这种情况下为java
)变为PID = 1并接收终止信号,而没有exec
则获得了其他PID和没有收到信号,因此无法杀死。
所以我的问题有两个:
exec
一样在不成功退出容器的情况下终止进程?exec
(在本例中为rm
之后的清理工作?答案 0 :(得分:1)
您可以创建一个入口点bash脚本,以捕获CTRL-C信号,杀死(或正常停止?)Java进程,然后进行清理。
示例(未经测试):
#!/bin/bash
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
echo "Trapped CTRL-C"
# Do something here. Kill Java?
}
java -jar "./lib/Saxon-HE-${SAXON_VER}.jar" -s:"$json_xml" -xsl:"$STYLESHEET" base-uri="$base"
将其添加到您的docker映像中,并将其作为入口点
FROM java:8
ADD docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
答案 1 :(得分:1)
我用蒂尼。这是参考文献link
答案 2 :(得分:1)
您可以仅构建另一个程序来管理java子进程和清理,例如使用相同的java
,go
或rust
编写这样的程序。我确定这些语言都有适当的过程控制工具,并且您可以捕获CTRL-C和其他事件以停止内部子进程并进行清理。与搜索行为有限的工具相比,可能甚至会花费更少的时间。对于此类问题,甚至值得开源。