要求是设置一个每4秒运行一次的cron作业。由于cron作业只能在几分钟内执行,因此我决定每分钟触发一次作业,并在该作业内多次运行它。这是代码。
public function handle()
{
$dt = Carbon::now();
$counter = 60/4; //run the job every 4 seconds
do {
//logic goes here
// add data to database
time_sleep_until($dt->addSeconds(4)->timestamp);
} while ($counter-- > 0);
}
Cron作业的计划与crontab -e相同
*/1 * * * * /usr/bin/php /var/www/html/dashboard/artisan cronjob:pulldata
当我使用php artisan命令手动执行作业时,作业每4秒会完美运行一次。但是,当它由crontab -e的cronjob触发时,它仅每分钟执行一次。
答案 0 :(得分:1)
您应该做的是有15个cron作业,每个作业每分钟运行一次,第一个作业偏移零秒,第二个作业偏移4秒,8秒,12,依此类推
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 4; /path/to/executable param1 param2 )
* * * * * ( sleep 8; /path/to/executable param1 param2 )
...
或者有一个单独的cron作业可以将(command && sleep 4) &
链接15次
答案 1 :(得分:-1)
我不知道到底出了什么问题。但是问题之一可能是服务器无法阻止连续执行1分钟的脚本。有一种解决方法。
您可以做的是创建一个单独的bash脚本,该脚本每x秒调用一次artisan命令。就像this Ubuntu answer
中的建议#!/bin/bash
while true; do
/usr/bin/php /var/www/html/dashboard/artisan cronjob:pulldata
sleep 4;
done
然后在您的cronjob中调用此脚本:
*/1 * * * * /var/www/html/dashboard/your-command.sh
答案 2 :(得分:-1)
我会这样做,因为您每分钟启动一次cron作业,所以您必须考虑到每次迭代中实际数据库逻辑从1分钟内消失的时间,以防止重叠:
public function handle()
{
$minute = 60;
do {
$start = microtime(true);
// Your Database Logic
$end = microtime(true);
sleep(4);
$minute = $minute - (4 + (($end - $start) / 60));
} while ($minute > 0);
}
此外,您应该考虑将此操作作为后台进程仅运行一次,可以通过在控制台调用php artisan your:command &
中添加&符号来实现,然后可以这样编写,但请确保将其清除设置逻辑中所有不必要的变量,以防止占用大量内存:
public function handle()
{
try {
$this->process();
} catch (\Exception $e) {
// Log your error somewhere
Log::error($e->getMessage());
// Re-run process
$this->process();
}
}
protected function process()
{
while(true) {
// Your Database Logic
sleep(4);
}
}