我有一个在 wordpress cron.php 文件上运行 PHP 的 cronjob。它主要用于安排发布,我相信它可能会刷新缓存。
我每分钟运行一次 cron 作业。我经常检查 ps,看到两个 PHP 实例正在运行 cron.php。现在这是不必要的,因为运行一个实例将完成它需要做的一切。我还有另一项工作,检查内存,有时有两个实例会导致内存崩溃(我希望始终有大量内存可用,我可以降低它,但我不想这样做)。我几乎不相信一项工作会花费超过一分钟(尽管可能)。
如果进程已经存在,我该如何运行作业?我不认为 PHP 代码本身可以检查,除非它连接/使用数据库?有我可以使用的 cron 命令吗?我不想杀死一个超过 1 分钟的实例。只是不产生新的。
答案1
这是一个简单的 bash 脚本解决方案;您可能可以在 cron.php 脚本中执行相同的操作。它实际上会检查运行时间过长的进程;对于自动化系统来说,这可能是一个好主意。
#!/bin/bash
# Exit if process is already running
if test -e /tmp/wordpress-job.pid; then
# Check if the pid that was stored in /tmp/wordpress-job.pid does exist
if ps ax -o pid= | grep $(cat /tmp/wordpress-job.pid ) &> /dev/null; then
exit 0
fi
fi
# Create the file that marks this process as running
echo $$ > /tmp/wordpress-job.pid
# Some extra security check to prevent the pid file
# to survive.
trap "rm -f /tmp/wordpress-job.pid" EXIT TERM INT HUP
# Start the long-running process in the background
sleep 3600 & # long-running process
# Sleep some time before trying to kill that process
sleep 300
# Kill job if it takes longer than it should
kill %1
# Delete the file that marks this process as running
rm -f /tmp/wordpress-job.pid
您必须用 php 命令行替换“sleep 3600”,并将下面的 300 更改为允许脚本运行的最长时间。
答案2
让你的 crontab 条目运行:
if mv /var/run/my-php-job.pending /var/run/my-php-job.running 2>/dev/null; then
echo $$ >|/var/run/my-php-job.running # optional
… # run the job
: >|/var/run/my-php-job.running # optional
mv /var/run/my-php-job.running /var/run/my-php-job.pending
fi
将其放入@reboot
crontab 条目中:
rm -f /var/run/my-php-job.running
touch /var/run/my-php-job.pending
文件名充当锁。虽然它是.running
,但有一个正在运行的作业,而下一个作业将不会开始。当它为 时.pending
,正在运行的作业将启动并切换到.running
。
如果包含可选行,shell 的进程 ID 将写入文件.running
,以便在作业卡住时进行调查。日志文件将使这变得多余。
如果运行作业的 shell 崩溃(这种情况不太可能发生,并且只有在有人故意杀死它或内存不足的情况下才会发生这种情况,锁定文件将卡在.running
。(如果作业本身崩溃,那没有问题。)您可以检测先前脚本的突然死亡,但这要困难得多。
答案3
有一些特殊的实用程序可以避免并行运行:util-linux中的flock、BSD系统中的lockf、NetBSD中的shlock以及INN和cnews包。
对于最可能的情况(Linux),调用类似于:
flock -w 60 /somedir/lockfile cron.php
其他答案中的食谱是本土羊群的替代品,仅在缺乏此类工具的情况下才有用。
OTOH,您可以直接在程序中处理此类锁定,但您应该仔细重复所有细节,否则您可能会创建竞争条件。