我正在Linux / Apache上用PHP开发应用程序。我希望能够在应用程序内的某个特定时间安排PHP作业(脚本)执行。
我知道很多人会推荐cron和at,但首先我不需要重复(cron),其次,最重要的是,我需要解决方案才能扩展。在设计时没有考虑到种族歧视,如果两个用户同时尝试添加一个作业,其中一个或两个可能会失败。
在指定的时间执行作业也很重要,而不是每分钟左右“轮询”一次。
有人可以为此任务建议解决方案吗?谢谢。
答案 0 :(得分:2)
将php脚本编写为守护进程 脚本在后台运行,每隔几微秒唤醒一次,检查要执行的任务。如果它有一些要执行的任务,它可以自行分叉并启动任务。
如果您不喜欢,脚本每微秒唤醒一次,您还可以计算下一个任务的睡眠时间,然后分叉启动它。当添加或删除任务时,只需向程序发送信号然后唤醒并重新计算它现在要睡多久。
超链接:
http://en.wikipedia.org/wiki/Daemon_%28computer_software%29
答案 1 :(得分:0)
您可以尝试gearman
答案 2 :(得分:0)
这是你可以(我愿意)做的事情:
答案 3 :(得分:0)
在POSIX系统上,应该有at-daemon,它基本上是cron的一次性版本:
$ at 13:20 executeVeryImportantScript.php withPositionalParameters taken
可以通过php的exec调用(或者用于通过php执行shell命令的任何东西)。
重新实现已有的解决方案非常糟糕的做法:
答案 4 :(得分:0)
这是使用MySQL的Yii2的解决方案。如果将查询/状态更新放在事务中,则可以在不同的计算机上安装多个工作程序。
cron table
Field | Type
--------------+-------------
id | int(11)
execute_after | timestamp
executed_at | timestamp
status | int(11)
progress | int(11)
action | varchar(255)
parameter | varchar(255)
result | varchar(255)
Cron class
/** This command waits for jobs to work on by polling the DB every 10s. TODO put this into Redis.
*
*/
public function actionIndex()
{
do {
$job = Cron::find()->where('execute_after < :now AND status = 0 ORDER BY id ASC', [':now'=>date(DATE_ATOM)])->one();
if($job && method_exists($this, $job->action)){
$job->status = 1;
$job->save() or Yii::error($job->getErrors());
$result = $this->{$job->action}($job, $job->parameter);
$job->status = 2;
$job->progress = 100;
$job->executed_at = date(DATE_ATOM);
$job->save() or Yii::error($job->getErrors());
}
sleep(10);
} while (true);
}
然后你可以在类中拥有任务,如
function toggleStatus($job, $id) {
完成工作并在工作完成时更新工作进度。