我有一個在 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,您可以直接在程式中處理此類鎖定,但您應該仔細重複所有細節,否則您可能會建立競爭條件。