我正在尝试如何在Laravel上写作业。
在Laravel文档之后,我创建了一个使用mail:queue。
发送电子邮件的简单作业我还添加了一个cron作业,它将每分钟调用一次调度程序,然后每5分钟运行一次该作业。
当我手动运行命令队列时,一切正常:listen。
后来我在调度程序中添加了一个print语句,我发现了一个奇怪的问题。
每当我运行队列时:从终端收听,我会看到日程安排功能内的打印消息,并且每5秒打印一次。
所以我的问题是队列:监听调用日程安排功能吗?如果是,为什么我们需要添加 schedule:run 作为cron作业?
我使用的代码:
protected function schedule(Schedule $schedule){
error_log("inside scheduler");
$schedule->call(function () {
dispatch(new \App\Jobs\SendEmail);
})->everyFiveMinutes();
}
这是我在终端上运行的命令。
php artisan queue:listen
我得到的输出(每5秒)
内部调度程序
内部调度程序
内部调度程序
...
有人能解释一下这里发生了什么吗?
- 添加工作代码以便更好地理解
SendEmail.php
public function handle() {
//do some task here
Mail::queue("emails.send_update", [], function($message) {
$message->to("someone@somedomain.com");
$message->subject('Status has been updated');
});
}
答案 0 :(得分:5)
队列和日程安排是不同的事情。
<强> Queues 强> 您可以设置在服务器上运行的邮件队列。这总是在倾听。如果您向邮件队列添加电子邮件,您的队列函数将尽快执行邮件发送:它只是在不同的线程上执行此操作。
<强> Scheduling 强>
这是Laravel组织cron工作的一种方式。 Laravel建议您在服务器上设置一个cron命令,该命令每分钟执行一次schedule:run
。在此命令中,Laravel会查看您设置的调度脚本及其条件,并在需要执行时为您执行适当的调度脚本。
当涉及到您的邮件任务时:您应该将邮件添加到作业队列,并将其保留。不涉及安排。然后在您的服务器上,您将使用queue:listen
运行队列:当邮件添加到队列时,它将立即发送。
在您的服务器上还为任何调度脚本设置了cron命令(如调度:启动调度程序中所述),但您可以忘记已经设置了cron。然后你可以创建自己的调度脚本,以便在特定时间执行,Laravel将为你发挥其魔力。
更新回复: 在SendEmail.php函数中,您需要处理正在发送的邮件的任务:类似
public function handle(Mailer $mailer)
{
$mailer->send('emails.reminder', ['user' => $this->user], function ($m) {
//
});
}
目前,您每5分钟向队列中添加一个新作业,但您的工作是将电子邮件排队。所以你有效地不断排队消息但从未真正执行它们。
答案 1 :(得分:0)
queue:listen
将在Kernel.php中部分执行'schedule()'函数,使其在代码中定期输出内容。将queue:listen
更改为queue:work
将解决此问题。
有关详细信息,请参阅此laravel cannot run scheduled command, while queue:listen run schedule() periodically和answer。