queue:work --daemon 和 queue:listen 有啥区别

Posted

技术标签:

【中文标题】queue:work --daemon 和 queue:listen 有啥区别【英文标题】:What is the difference between queue:work --daemon and queue:listenqueue:work --daemon 和 queue:listen 有什么区别 【发布时间】:2014-11-20 19:46:08 【问题描述】:

我正在设置我的离线作业服务器。我已经阅读了文档,但我仍然没有真正看到这两个命令之间的区别:artisan queue:work --daemonartisan queue:listen。我应该使用哪个命令来运行我的守护进程?

【问题讨论】:

【参考方案1】:

编辑于 2017 年 4 月 7 日更新:

现在有三种运行队列的方法:

queue:work - 这是新的“守护进程”进程(不再需要该标志)。该框架将启动“一次” - 然后继续循环遍历作业。这将无限期地持续下去。它使用的内存/cpu 比queue:listen 少,因为框架一直处于运行状态。您还必须记住使用queue:restart 强制队列更新您在修补期间推送的任何代码更改。

queue:work --once - 这将启动框架,处理一项作业,然后关闭。对开发过程中的测试等很有用。

queue:listen - 这将在每个周期启动框架,处理一个作业,然后完全关闭,然后再次启动框架等等并无限循环。这意味着在处理每个作业后释放所有内存/进程。如果你有 queue:work 的内存泄漏 - 试试这个。

--daemon 标志不再对这些命令产生影响。

原答案:

列出了两个不同的问题。

artisan queue:workartisan queue:listen

queue:work 将简单地弹出队列中的下一个作业,并且只处理那个作业。这是一个“一次性”命令,一旦处理完一个队列命令,它将返回到命令提示符。 queue:listen 将监听队列,并继续处理它收到的任何队列命令。这将无限期地继续运行,直到您将其停止。

在 Laravel >=4.2 中添加了 --daemon 命令。它的工作方式只是直接运行队列,而不是在处理完每个队列后重新启动整个框架。这是一个可选命令,显着降低了队列的内存和 CPU 需求。

--daemon 命令的重要一点是,当您升级应用程序时,您需要专门使用 queue:restart 重新启动队列,否则您可能会遇到各种奇怪的错误,因为您的队列仍然有旧的内存中的代码。

所以要回答您的问题“我应该使用哪个命令来运行我的守护进程?” - 答案几乎总是queue:work --daemon

【讨论】:

如何在后台运行守护进程?我应该把代码放在哪里重新启动队列? 如果您使用 --daemon 标志运行,您需要认真对待文档中的内存警告。如果您正在处理大文件或执行其他内存密集型操作,则该进程可能会泄漏至少一些内存并最终崩溃。我什至尝试在这些作业中释放内存,但收效甚微。最好使用 Supervisor 来生成新的 Queue::work 进程。 我仍然不明白 queue:listen 和 queue:work --daemon 之间的区别。 queue:listen 无限期运行而 queue:work --daemon 也无限期运行而不重新加载框架,那么有什么区别呢? 工作和聆听似乎几乎是一回事,但在底层存在一些差异。如何处理队列然后退出而不监听更多事件? @Lucas - 是的,正确的。您要么处理一项工作并退出,要么无限期地处理。两者之间没有。【参考方案2】:

最重要的区别是queue:work --daemon 不会在每个job 上重新启动框架,但queue:listen 。事实上,listen 为每个作业启动了一个全新的 Laravel 进程。

亲自尝试:打开 2 个终端,在一个终端运行 work --daemon,在另一个终端运行 listenwork 窗口将比 listen 更快地执行作业。

【讨论】:

【参考方案3】:

Things have been changed但是文档中没有提到

 --daemon  Run the worker in daemon mode (Deprecated)

现在默认 php artisan queue:work 以守护模式运行,

所以queue:work 继续处理作业而无需重新启动框架

运行一次命令是,

php artisan queue:work --once

【讨论】:

不正确,它不会在守护程序模式下运行,它会保持用户界面打开并且不会在后台运行...【参考方案4】:

从 Laravel 5.7 开始,--stop-when-empty 已添加到 queue:work 命令中。使用此选项时,当前队列将被处理,直到它为空,然后命令将退出。

根据documentation:

--stop-when-empty 选项可用于指示工作人员处理所有作业,然后正常退出。如果您希望在队列为空后关闭容器,则此选项在使用 Docker 容器中的 Laravel 队列时很有用:

php artisan queue:work --stop-when-empty

【讨论】:

以上是关于queue:work --daemon 和 queue:listen 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

Docker + Laravel 队列:工作

Laravel 运行队列处理器 queue:work 与 queue:listen 区别及 Windows 终端命令问题

Laravel 运行队列处理器 queue:work 与 queue:listen 区别及 Windows 终端命令问题

在使用数据库作为队列连接的 laravel 作业中。但是 queue:work 命令不触发队列?

queue stack 用法

等待队列_睡眠和唤醒