我有一个每分钟运行 php5 wp-cron.php 的 cronjob 来更新我的网站。
然而发生了一些事情,我有 30 多个这样的实例(在这个转储中标记了 31 个ps aux
)。它耗尽了我的内存,导致额外的实例因内存不足而终止 do,并导致我无法 ssh 进入盒子。
我不明白为什么实例的生存时间>30分钟,一个实例通常需要几秒钟。事情发生的那天我没有计划任何工作(虽然也许 wp 缓存使用了它?但我以前从未遇到过问题)
我该怎么做才能防止 cronjob 发送垃圾邮件并破坏我的内存?有没有办法我可以说如果实例还活着就不要启动?如果一个实例存活时间超过 5 分钟,就会杀死它吗?
有什么办法可以保护自己免受类似事情的发生吗?
答案1
我认为你需要做的第一件事就是激起可能导致该工作 31 次发生的罪魁祸首。通常这可能是您的程序在某个时刻挂起,您应该调试并修复此问题,除非您不希望您的网站成功更新。
对于“如果实例还活着,我可以说不启动吗”,是的,有几种方法,其中一种只是检查pgrep yourprogramname
实例是否已经存在,如果是,您可以调用pkill -x yourprogramname
杀死它们全部。
答案2
为了防止多副本运行的目标,可以使用flock(Linux)、lockf(FreeBSD)、shlock(部分系统提供,可靠性较差)。这不会限制执行时间,但会确保只有一个进程正在运行。然后,如果它挂起,您可以动态分析其状态。
您可以使用 ulimit shell 内置命令限制生成进程的 CPU 时间。
为了限制挂起时间,您可以编写等待进程终止并在超时后终止它的脚本。在 Python/Perl/等中更容易。但 shell 也允许这样做(使用 trap 和/在背景子项上)。
有时,在调用之间提供固定的时间(即从上一个调用结束到下一个调用开始)而不是像 cron 那样调用开始是有用的。通常的 cron 不允许这样做,你应该运行特殊的脚本。