我正在使用cronjob来运行将每1分钟执行一次的php脚本
我还需要确保只运行副本,所以如果这个php脚本在2分钟后仍在运行,那么cronjob不应该运行另一个版本。
目前我有2个选项,我希望看到您的反馈,如果您有更多选择
选项1:当php脚本启动时创建一个tmp文件,当php脚本完成时删除它(并检查文件是否存在)--->我有这个选项的问题是,如果我的PHP脚本因任何原因崩溃,它将不会再次运行(tmp文件不会被删除)
选项2:运行类似下面的bash脚本来控制php脚本执行--->好,但寻找可以在PHP内完成的事情
#!/bin/bash
function rerun {
BASEDIR=$(dirname $0)
echo $BASEDIR/$1
if ps -ef | grep -v grep | grep $1; then
echo "Running"
exit 0
else
echo "NOT running";
/usr/local/bin/php $BASEDIR/$1 &
exit $?
fi
}
rerun myphpscript.php
PS:我刚刚在http://www.php.net/manual/en/class.mutex.php看到了“Mutex课程”,但不确定它是否稳定且有人试过。
答案 0 :(得分:1)
您可能希望使用我的库ninja-mutex,它提供了处理互斥锁的简单界面。目前它可以使用flock,memcache,redis或mysql来处理锁定。
下面是一个使用memcache的例子:
<?php
require 'vendor/autoload.php';
use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\Mutex;
$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211);
$lock = new MemcacheLock($memcache);
$mutex = new Mutex('very-critical-stuff', $lock);
if ($mutex->acquireLock(1000)) {
// Do some very critical stuff
// and release lock after you finish
$mutex->releaseLock();
} else {
throw new Exception('Unable to gain lock!');
}
答案 1 :(得分:1)
我经常在我的crontabs中直接使用许多Linux发行版附带的程序flock
,如:
* * * * * flock -n /var/run/mylock.LCK /usr/local/bin/myprogram
原因是如果你手动执行它仍然可以实际启动两个myprogram实例,但是crond只能创建一个。
Flock是一个小型的编译二进制文件,与最终的大量php代码相比,它的启动速度非常快。如果您有许多更长时间运行的执行,这尤其是一个好处,实际上并不是很清楚。
答案 2 :(得分:0)
如果您没有使用NFS挂载,可以使用flock()(http://php.net/manual/en/function.flock.php):
$fh = fopen('guestbook.txt','a') or die($php_errormsg);
$tries = 3;
while ($tries > 0) {
$locked = flock($fh,LOCK_EX | LOCK_NB);
if (! $locked) {
sleep(5);
$tries--;
} else {
// don't go through the loop again
$tries = 0;
}
}
if ($locked) {
fwrite($fh,$_REQUEST['guestbook_entry']) or die($php_errormsg);
fflush($fh) or die($php_errormsg);
flock($fh,LOCK_UN) or die($php_errormsg);
fclose($fh) or die($php_errormsg);
} else {
print "Can't get lock.";
}
答案 3 :(得分:0)
我发现最适合我的解决方案是为脚本创建一个单独的数据库用户,并将该用户的concurent连接限制为1。