5

我在一个 Ubuntu 15.04 容器中运行 Stardog 4.0,并带有运行良好的开放 jdk8。我想使用陷阱优雅地关闭stardog 。

要在容器中执行 stardog 以便它继续运行,我一直在使用以下效果很好

$SBIN/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done

如果没有以下内容,容器将运行几秒钟并停止

&& (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done

然而,这会导致容器内有多个 PID

root         1  0.0  0.0  18384  3236 ?        Ss   14:04   0:02 /bin/bash /stardog_binaries/startup.sh
root        45  0.1  4.9 4619052 406940 ?      Sl   14:04   0:10 java -Xms2g -Xmx2g -XX:MaxDirectMemorySize=4g -XX:SoftRefLRUPolicyMSPerMB=1 -XX:+UseParallelOldGC -XX:+UseCompressedOops -Djavax.xml.datatype.DatatypeFactory=org.apache.xerc
root        97  0.0  0.0   4412   740 ?        S    14:04   0:00 tail -f /storage/stardog.log
root     12108  0.2  0.0  18184  3100 ?        Ss   15:44   0:00 bash
root     12122  0.0  0.0   4376   784 ?        S    15:44   0:00 sleep 1

当容器关闭时,以下陷阱无法关闭stardog

trap 'kill -TERM $PID' TERM INT
$SBIN/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done
PID=$!
wait $PID
trap - TERM INT
wait $PID
EXIT_STATUS=$?

所以我的问题是如何正确捕获 $SBIN/bin/stardog-admin 服务器启动,以便在容器关闭时,stardog 优雅地退出。

问候康泰

4

2 回答 2

1

您可以使用专门制作的图像来处理此类问题,例如phusion/baseimage-docker.

请参阅“ PID 1 僵尸收割问题”:通过将脚本声明为守护进程,您将确保映像正确处理关闭信号。

于 2015-11-27T16:34:59.973 回答
1

最后,我在容器中创建了一个 runstardog.sh 脚本。

set -e
function shutdown() {        
 $STARDOG_BINARIES/bin/stardog-admin server stop  -p xxx -u admin    
}

$STARDOG_BINARIES/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done

trap "{ shutdown }" EXIT
exit 0

由包含以下陷阱的 startup.sh 脚本执行

trap 'kill -TERM $PID' TERM INT
$STARDOG_BINARIES/runstardog.sh &
PID=$!
wait $PID
trap - TERM INT
wait $PID
EXIT_STATUS=$?

然后当我想停止服务器时,我在托管容器的服务器上调用 stop.sh,该容器标识了 stardog 容器的 CID,使用 docker exec 关闭 stardog 并停止并删除容器。

replace="\1"
find="([a-z0-9]{12})\s+platform_stardog.*"
CID=$( docker ps | tail --lines=+2 | sed "/platform_stardog/!d"  | perl -lpe  "s@$find@$replace@g"  )

if [ -z "$CID" ]; 
then
    echo "No existing container named platform_stardog was found"
else
    echo "docker exec  /stardog_binaries/stopstardog.sh in platform_stardog Container $CID:"
    docker exec ${CID} /stardog_binaries/stopstardog.sh
    echo "stop and delete docker container."
    /usr/local/bin/docker-compose -p platform -f docker-compose.yml stop -t 30 stardog && /usr/local/bin/docker-compose -p platform -f docker-compose.yml rm --force -v stardog
fi

由于stardog 的输出“Stardog 服务器成功接收到关闭请求”并且关闭过程不需要很长时间,我得到确认这是有效的。它曾经挂起通过 docker compose stop -t 30 指定的 30 秒

谢谢@VonC,接下来我会尝试这种方法。

于 2015-11-28T14:29:54.857 回答