0

要求是设置一个每 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 触发时,它每分钟只执行一次。

4

3 回答 3

1

您应该做的是有 15 个 cron 作业,每个作业每分钟运行一次,第一个偏移 0 秒,下一个偏移 4 秒、8 秒、12 秒,依此类推

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 4; /path/to/executable param1 param2 )
* * * * * ( sleep 8; /path/to/executable param1 param2 )
...

或者有一个链接(command && sleep 4) &15 次的 cron 作业

于 2018-10-01T09:11:59.537 回答
-1

我不知道到底出了什么问题。但是其中一个问题可能是您的服务器阻止了持续执行 1 分钟的脚本。有一种方法可以解决这个问题。

您可以做的是创建一个单独的 bash 脚本,每隔 x 秒调用一次您的工匠命令。就像在这个 Ubuntu 答案中建议的那样

#!/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
于 2018-10-01T08:55:09.703 回答
-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);
     }
}
于 2018-10-01T11:00:00.313 回答