【问题标题】:How to get supervisord to restart hung workers?如何让主管重新启动挂起的工人?
【发布时间】:2017-09-25 16:38:50
【问题描述】:

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

我们已经使用http://superlance.readthedocs.io/en/latest/memmon.html 在内存使用量猛增时终止,这可以缓解一些挂起,但不会导致内存泄漏的挂起仍会导致工作人员陷入停顿。

【问题讨论】:

    标签: background-process supervisord worker


    【解决方案1】:

    一种可能的解决方案是将您的 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 脚本会做类似的事情。

    【讨论】:

    • 谢谢!那里发生了很多事情,感谢您写下这篇文章!用于轮询的后台进程,通过信号向主脚本发出信号;一个临时的 FIFO,以确保主脚本获得子脚本的输出;在任何出口处代理子级的正确信号处理(SIGINT 和 SIGTERM 触发我刚刚学到的trap ___ EXIT!)应该猜到这是解决它的正确方法 - 主管没有必要处理所有业务逻辑,如果包装脚本可以做得更好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 2020-11-15
    • 2012-12-14
    • 2015-01-01
    • 1970-01-01
    • 2016-08-16
    相关资源
    最近更新 更多