在Docker里应用监听不到Signal怎么办?
# 问题描述
最近程序在docker里运行时,signal.Notify(sigChannel, syscall.SIGINT, syscall.SIGTERM)收不到信号了,导致发版时程序不能优雅关闭。
调查发现最忌的改动是把Dockerfile里的CMD由原先的bin文件改为了shell脚本。如下图:

# 问题原因
经过搜索了解到,Docker stop的signal只会发给1号进程,CMD启动的就是1号进程。在本次案例中,本来CMD直接启动Bin文件,所以是可以直接收到Signal的。而改为Shell脚本后,Shell脚本是1号进程,由Shell脚本启动的Bin变成了x号进程。所以我们需要让Shell脚本收到的Signal转发给x号进程。
# 解决方案
#!/bin/bash
prep_term()
{
unset term_child_pid
unset term_kill_needed
trap 'handle_term' TERM INT
}
handle_term()
{
if [ "${term_child_pid}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
else
term_kill_needed="yes"
fi
}
wait_term()
{
term_child_pid=$!
if [ "${term_kill_needed}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
fi
wait ${term_child_pid}
trap - TERM INT
wait ${term_child_pid}
}
run() {
./bin/server -mode cluster &
}
run_with_ddns() {
./launcher -name zt-ddgw-internal -port 8088 ./bin/server -mode cluster &
}
prep_term
if [ $RUN_WITH_DDNS ]; then
run_with_ddns
else
run
fi
wait_term
# 参考内容
- https://www.cnblogs.com/sparkdev/p/7598590.html
- https://unix.stackexchange.com/questions/146756/forward-sigterm-to-child-in-bash
- 原文出处:
- 原文作者: https://github.com/saltbo
- 原文链接:
- 版权声明:本文欢迎任何形式转载,转载时完整保留本声明信息(包含原文链接、原文出处、原文作者、版权声明)即可。本文后续所有修改都会第一时间在原始地址更新。