如何让主管重新启动挂起的工人?

How to get supervisord to restart hung workers?

我有许多 Python 由 supervisord 管理的工人,如果他们工作正常,他们应该连续打印到标准输出(在每个完成的任务之后)。然而,它们往往会挂起,我们很难找到错误。理想情况下,supervisord 会注意到他们在 X 分钟内没有打印并重新启动它们;任务是幂等的,因此非正常重启是可以的。是否有任何 supervisord 功能或插件可以做到这一点?或者另一个开箱即用的类似主管的程序?

我们已经在使用 http://superlance.readthedocs.io/en/latest/memmon.html 来终止内存使用量激增的情况,这可以缓解一些挂起,但不会导致内存泄漏的挂起仍然会导致工作进程停顿。

一个可能的解决方案是将您的 python 脚本包装在一个 bash 脚本中,该脚本将监视它并在一段时间内没有输出到标准输出时退出。

例如:

kill-if-hung.sh

#!/usr/bin/env bash
set -e

TIMEOUT=60
LAST_CHANGED="$(date +%s)"

{
    set -e
    while true; do
        sleep 1
        kill -USR1 $$
    done
} &

trap check_output USR1

check_output() {
    CURRENT="$(date +%s)"
    if [[ $((CURRENT - LAST_CHANGED)) -ge $TIMEOUT ]]; then
        echo "Process STDOUT hasn't printed in $TIMEOUT seconds"
        echo "Considering process hung and exiting"
        exit 1
    fi
}

STDOUT_PIPE=$(mktemp -u)
mkfifo $STDOUT_PIPE

trap cleanup EXIT
cleanup() {
    kill -- -$$ # Send TERM to child processes
    [[ -p $STDOUT_PIPE ]] && rm -f $STDOUT_PIPE
}

$@ >$STDOUT_PIPE || exit 2 &

while true; do
    if read tmp; then
        echo "$tmp"
        LAST_CHANGED="$(date +%s)"
    fi
done <$STDOUT_PIPE

然后你会 运行 supervisord 中的 python 脚本,如:kill-if-hung.sh python -u some-script.py-u 禁用输出缓冲,或设置 PYTHONUNBUFFERED)。

我相信您可以想象一个 python 脚本会做类似的事情。