Laravel 非重叠计划作业未执行

问题描述 投票:0回答:6

我在

Kernel.php
中定义了一个 Laravel 计划作业。

$schedule->call('\App\Http\Controllers\ScheduleController@processQueuedMessages')
    ->everyFiveMinutes()
    ->name('process_queued_messages')
    ->withoutOverlapping();

在开发过程中,我的工作由于语法错误引发了异常。我纠正了错误并尝试再次执行,但还是不行。

我尝试了

artisan down
,然后
artisan up
。我还尝试重新启动服务器实例。但没有任何帮助。作业只是没有被执行(也不例外)。

我意识到问题是由于

->withoutOverlapping()
造成的。不知何故,Laravel 调度程序认为该作业已经在运行,并且不会再次执行它。

laravel laravel-5
6个回答
10
投票

注意:此解决方案适用于 Laravel 5 Laravel 的后续版本更新了

withoutOverlapping()
功能。请参阅@nmargaritis 的回答。


我通过查看供应商代码找到了解决方案。

Illuminate\Console\Scheduling\CallbackEvent.php

它会在本地存储中创建一个名为

schedule-*
的文件。

public function withoutOverlapping()
{
    if ( ! isset($this->description))
    {
        throw new LogicException(
            "A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
        );
    }
    
    return $this->skip(function()
        {
            return file_exists($this->mutexPath());
        });
}

protected function mutexPath()
{
    return storage_path().'/framework/schedule-'.md5($this->description);
}

删除位于

schedule-*
的文件
storage/framework
解决了问题。


9
投票

对于阅读本文的任何人来说,自己删除计划文件并不是正确的方法。您需要指定 - 锁定时间 - 在此基础上,withoutOverlapping 会阻止进一步的任务运行。

Laravel - 任务调度

中所引用

如果需要,您可以指定“无重叠”锁定到期之前必须经过多少分钟。默认情况下,锁定将在 24 小时后过期:

您的问题源于 withoutOverlapping 应用了 24 小时的默认锁定。所以你必须等待24小时才能接受类似的任务。只需根据您的需要调整锁定时间即可:

$schedule->command('emails:send')->withoutOverlapping(10); // 其中 10 指分钟


5
投票

这对我有用:

php artisan cache:clear

5
投票

我也遇到这个问题了。对此没有适当的解决方案,但解决方法可以解决该问题。

转到项目的存储/框架文件夹并删除所有

schedule-***********
文件。

然后再次尝试运行 cron。即使您使用

withoutOverlapping() function
也会如此。

希望这对您有用。有疑问就问吧。


3
投票

从 Laravel 8.x 开始,您可以使用特定命令清除互斥文件,例如,如果任务在执行时由于服务器重新启动而卡住

clear:cache
的问题是这个命令清除整个应用程序的缓存,而这个命令只是清除互斥文件

php artisan schedule:clear-cache

0
投票

这周发生在我们身上,我们认为我们找到了原因。我们的 cron 运行在我们的生产服务器的站点文件夹之一上。我们的部署过程涉及建立第二个文件夹,我们在其中进行部署/构建,然后在最后进行热文件夹交换。由于 withoutOverlapping() 可能需要在进程完成时更新 Schedule-* 文件中的一行,因此文件夹可能会在作业中被交换,并且 cron 无法成功地将作业标记为已在正确的 Schedule-* 文件中完成,所以它认为它仍在运行/卡住。

这种情况很少发生,但我们将添加一个命令来在部署后清除这些文件,这样就不会再发生这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.