【问题标题】:How to detect unresponsive/frozen processes?如何检测无响应/冻结的进程?
【发布时间】:2013-02-26 10:02:25
【问题描述】:

我有几个用于进行网络爬取的脚本。它们一直在运行,并且永远不应该停止。然而,大约一周后,它们系统地“冻结”:不再有输出,对 Ctrl+C 或任何东西都没有响应。唯一的方法是kill该进程并重新启动它。

我怀疑这些问题来自我用于检索数据的库 (urllib2),但问题很难重现。

因此,我想知道如何检查进程的状态并在它被冻结时自动杀死/重新启动它。我正在考虑创建一个 PID 文件,并定期更新它。然后另一个脚本可以定期检查此 PID 文件的最后修改日期,如果它太旧,则重新启动该进程。我可以使用Monit 之类的东西来进行监控。

我应该这样做吗?是否有另一种检查流程响应能力的最佳实践/常用方法?

【问题讨论】:

  • 本着只做最简单的事情的精神,你不能只拥有一个永远调用你 Python 脚本的 shell 脚本,并且 Python 脚本在“n”次爬行后完成。它可能无法解决根本问题,但可能会让您花费更多精力来分析抓取的数据。
  • 我同意,这种事情会奏效,如果我很快找不到好的解决方案,我会这样做。但我觉得我可以做得更好;)。
  • 我不太确定,但我认为这些进程的状态为“D”(man ps)。你不能做一个 cron 来检查给定进程是否有状态 D 吗?
  • 好点。下次发生这种情况时,我会检查状态。如果是这种情况,那么您的解决方案将起作用。
  • 我想知道当进程冻结时您的抓取处于什么状态,它处理了 1200 个链接中的 525 个,然后在重新启动时,您必须清除这 525 个链接并再次为该站点重新启动抓取;我想你也希望能够尝试做类似stackoverflow.com/a/133384/1481060 这样的事情,这样它就可以让你知道它卡在哪里了。

标签: python unix process monitoring


【解决方案1】:

如果您有一个始终在运行的进程,没有连接的终端,并且是进程组的领导者 - 那就是一个守护进程。毫无疑问,这些你都知道。

在这样的程序编码中有一些事实上的做法。一种是有一个信号处理程序,它接受 SIGHUP 并强制程序重新初始化自己。这意味着关闭所有打开的日志文件,重新读取配置脚本等。我不知道这对您的问题有多适用,但它有时可以解决我工作中的冻结守护进程等问题。

您可以通过使用SIGUSR1SIGUSR2 信号来自定义想法来执行特殊操作,例如将状态写入文件或其他任何事情。由于信号在中断时进入,脚本中的陷阱语句和 python 本身的信号处理程序会将程序状态推送到中断堆栈并执行“工作”。 在您的情况下,您可能需要程序 fork/exec 本身,然后杀死父级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 2012-08-13
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多