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

Posted

技术标签:

【中文标题】如何让主管重新启动挂起的工人?【英文标题】: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 在内存使用量猛增时终止,这可以缓解一些挂起,但不会导致内存泄漏的挂起仍会导致工作人员陷入停顿。

【问题讨论】:

【参考方案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!)应该猜到这是解决它的正确方法 - 主管没有必要处理所有业务逻辑,如果包装脚本可以做得更好!

以上是关于如何让主管重新启动挂起的工人?的主要内容,如果未能解决你的问题,请参考以下文章

windows server 2012r2 快速启动模式部署remoteapp,检查兼容性,显示有挂起的重新启动

如何让 Zeppelin 在 EMR 集群上干净地重新启动?

安装或卸载英特尔快速存储技术时,提示“此程序有一个挂起的重新启动”

解决win7下安装SQL2000时以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机!

sql server2000安装挂起的解决办法

主管不会在 econnrefused 上重新启动(在 init/1 中抛出)