了解 Laravel 5.2 上的队列和调度器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36625969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:36:48  来源:igfitidea点击:

Understanding Queues and Scheduler on Laravel 5.2

laravellaravel-5.2

提问by Santhosh Shet

I am experimenting on how to write jobs on Laravel.

我正在试验如何在 Laravel 上编写作业。

Following the Laravel documentation, I created a simple job that sends email using mail:queue.

根据 Laravel 文档,我创建了一个使用 mail:queue 发送电子邮件的简单作业。

I also added a cron job that will call the scheduler every minute which in turn will run the job every 5 minutes.

我还添加了一个 cron 作业,它将每分钟调用一次调度程序,然后每 5 分钟运行一次作业。

Everything works fine when I manually run the command queue:listen.

当我手动运行命令 queue:listen 时,一切正常。

Later I added a print statement inside the scheduler and I found a strange issue.

后来在scheduler里面加了一个print语句,发现了一个奇怪的问题。

Whenever I run the queue:listen from the terminal, I see the print message that is inside the schedule function and it gets printed every 5 seconds.

每当我运行 queue:listen 从终端时,我都会看到 schedule 函数中的打印消息,并且每 5 秒打印一次。

So my question is does queue:listencall the schedule function? If yes, why do we need to add schedule:runas a cron job?

所以我的问题是queue:listen调用调度函数吗?如果是,为什么我们需要添加schedule:runas a cron job?

The code that I used:

我使用的代码:

protected function schedule(Schedule $schedule){     
    error_log("inside scheduler");
    $schedule->call(function () {
        dispatch(new \App\Jobs\SendEmail);
    })->everyFiveMinutes();              
}

This is the command I ran on the terminal.

这是我在终端上运行的命令。

php artisan queue:listen

Output that I get (every 5 seconds)
inside scheduler
inside scheduler
inside scheduler ...


在调度程序
内的调度程序
内获得的输出(每 5 秒) ......

Can someone explain what is happening here?

有人可以解释这里发生了什么吗?

-Adding the job code for better understanding
SendEmail.php

-添加作业代码以更好地理解
SendEmail.php

 public function handle() {
 //do some task here
 Mail::queue("emails.send_update", [], function($message) {
  $message->to("[email protected]");
  $message->subject('Status has been updated');
 });
 }

回答by Tom

Queues and scheduling are different things.

队列和调度是不同的东西。

QueuesYou can set up a mail queue, that you run on the server. This is always listening. If you add an email to the mail queue, your queue function will execute the sending of the mail as soon as it can: it just does this on a different thread.

队列您可以设置在服务器上运行的邮件队列。这总是在听。如果您将电子邮件添加到邮件队列,您的队列函数将尽快执行邮件发送:它只是在不同的线程上执行此操作。

SchedulingThis is a way in Laravel for organising cron jobs. Laravel suggests you setup one cron command on your server that executes every minute called schedule:run. In this command, Laravel then looks at the scheduling scripts you've setup and their conditions, and executes the appropriate ones for you when they need to be executed.

调度这是 Laravel 中组织 cron 作业的一种方式。Laravel 建议您在服务器上设置一个 cron 命令,该命令每分钟执行一次,名为schedule:run. 在这个命令中,Laravel 然后查看您设置的调度脚本及其条件,并在需要执行时为您执行适当的脚本。

When it comes to your mail task: you should be adding the mail to the jobs queue, and leaving it like that. Don't involve scheduling. Then on your server you would just have the queue running with queue:listen: when a mail gets added to the queue, it will be sent immediately.

当涉及到您的邮件任务时:您应该将邮件添加到作业队列中,并保持原样。不涉及调度。然后在您的服务器上,您只需运行队列queue:listen:当邮件添加到队列时,它将立即发送。

On your server also setup the cron command for any scheduling scripts (as described under scheduling: starting the scheduler), but you can then forget that the cron was ever setup. Then you can just create your own scheduling scripts to be executed at certain times and Laravel will work its magic for you.

在您的服务器上还为任何调度脚本设置 cron 命令(如调度:启动调度程序中所述),但您可能会忘记 cron 曾经设置过。然后你可以创建自己的调度脚本在特定时间执行,Laravel 会为你发挥它的魔力。

Updated response: In your SendEmail.php function, you need to handle the task of a mail being sent: something like

更新响应:在您的 SendEmail.php 函数中,您需要处理正在发送的邮件的任务:类似

public function handle(Mailer $mailer)
{
    $mailer->send('emails.reminder', ['user' => $this->user], function ($m) {
        //
    });
}

At the moment, every 5 minutes you're adding a new job to the queue, but your job is to queue the email message. So you're effectively continually queuing messages but never really executing them.

目前,每 5 分钟您就会向队列中添加一个新作业,但您的工作是将电子邮件加入队列。因此,您一直在有效地对消息进行排队,但从未真正执行过它们。

回答by Kris Roofe

The queue:listenwill execute partly of 'schedule()' function in Kernel.php, which make it output contents periodically in your code. Change queue:listento queue:workwill solve this issue.

queue:listen会执行部分的“时间表()”在Kernel.php功能,这使得它定期输出的内容在你的代码。更改queue:listenqueue:work将解决此问题。

Refer this laravel cannot run scheduled command, while queue:listen run schedule() periodicallyand answerfor more information.

请参阅此laravel 无法运行计划命令,而 queue:listen 定期运行 schedule()回答以获取更多信息。