Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php cron作业中未触发Do While循环(Laravel)_Php_Laravel_Laravel 5_Cron - Fatal编程技术网

Php cron作业中未触发Do While循环(Laravel)

Php cron作业中未触发Do While循环(Laravel),php,laravel,laravel-5,cron,Php,Laravel,Laravel 5,Cron,要求是设置每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 t

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

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

您可以做的是创建一个单独的bash脚本,该脚本每x秒调用artisan命令。就像在

然后在cronjob中调用此脚本:

*/1 * * * * /var/www/html/dashboard/your-command.sh

您应该做的是有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 )
...

或者有一个单独的cron作业,它将
(command&&sleep 4)和
链接15次

我会这样做,因为您每分钟启动一次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);
}

另外,你应该把这个当作一个后台进程来做,你可以通过在控制台调用中添加AppSand符号来做:你的命令和,然后你可以这样写,但是一定要清除逻辑中的每一个不必要的变量,以防止高内存消耗:

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);
     }
}

您正在查看crontab日志还是4秒任务的实际结果?因为crontab只会每隔60秒向您显示一个新条目。您好,这是一个函数,您不会显示是否/如何调用它。它还调用一个你没有显示的函数。请记住,你必须为一个问题添加一些上下文,否则它对我们来说就像一个谜一样神秘you@MarkWalet,函数内部的逻辑是向数据库中的表添加条目。一分钟内必须有15个条目(每4秒),但只有1个条目,这意味着作业只执行了一次。如果我使用artisan命令手动运行,表中有15个条目。为了提高您的体验,请阅读如何询问,以及如何创建@RiggsFolly,逻辑是向表中添加数据。将更新问题。并且从服务器调用cron作业(crontab-e)。除此之外,没有其他背景,这不是问题所在。Dilani遇到了一个“bug”,循环每4秒执行一次代码,持续一分钟,但是当使用cronjob调用时,它不是。这只是一种更别致的4秒钟通话分配方式。我的回答提供了一种没有cron表的替代方法,你应该阅读整个回答。你否决了我的回答,说她的问题是关于一个bug,而你的第一句话是“我不知道到底出了什么问题”然后进一步了解你的偏好。你自己并没有给讨论增加任何价值。此外,在回答问题时,你应该提供例子,而不仅仅是一个链接。你是对的。我编辑了我的答案
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);
     }
}