ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 推送一个工作至队列 应用程序中能够放进队列的工作都存放在 App\Commands 目录下,你可以借由下面 Artisan 命令产生一个可使用队列的命令: `php artisan make:command SendEmail --queued` 要推送一个新的工作至队列,请使用 Queue::push 方法: ~~~ Queue::push(new SendEmail($message)); ~~~ > 注意: 在这个例子当中,我们直接使用 Queue Facade,然而,常见的作法是借由 Command Bus 去分派队列命令。我们将会在这篇文章中继续使用 Queue Facade,不过,也要熟悉使用 command bus,因为它能够同时分派你的网站应用程序中队列与同步的命令。 默认情况下,make:command Artisan 命令会产生一个 "self-handling" 的命令,意味着命令里会包含一个 handle 方法。这个方法将会在队列执行时被调用。你可以在 handle 方法使用时提示传入任何你需要的依赖,而 服务容器 会自动注入他们: ~~~ public function handle(UserRepository $users) { // } ~~~ 如果你希望你的命令有独立的处理类别,你可以在使用 make:command 命令时加上 --handler 标识。 `php artisan make:command SendEmail --queued --handler` 这个被产生出来的处理类别将会放在 App\Handlers\Commands 目录下面,并且服务容器会自动解析。 ## 指定队列使用特定连接 你也可指定队列工作送至指定的连接: `Queue::pushOn('emails', new SendEmail($message));` ## 发送相同的数据去多个队列工作 如果你需要发送一样的数据去几个不同的队列工作,你可以使用 Queue::bulk 方法: `Queue::bulk([new SendEmail($message), new AnotherCommand]);` ## 延迟执行一个工作 有时候你可能想要延迟执行一个队列工作,举例来说你希望一个队列工作在客户注册 15 分钟后才寄送 e-mail,你可以使用 Queue::later 方法来完成这件事情: ~~~ $date = Carbon::now()->addMinutes(15); Queue::later($date, new SendEmail($message)); ~~~ 在这个例子中,我们使用 Carbon 日期类库来指定我们希望队列工作希望延迟的时间,另外你也可发送一个整数来设置你希望延迟的秒数。 > 注意: 在 Amazon SQS 服务中,有最大 900 秒( 15 分钟 )的限制。 ## 将 Eloquent 模型放进队列 如果你队列工作的构造器接收一个 Eloquent 模型,只有这个模型的标记( identifier ) 会被序列化后放到队列中。当工作真正开始被处理的时候,队列系统会自动从数据库中重新取得完整的模型实例。这个对你的网站应用程序来说是完全透明的,并且预防一些在序列化完整 Eloquent 模型实例时可能遇到的问题。 ## 删除一个处理中的工作 一旦一个工作被处理过后,这个工作必须从队列中删除。假如在工作执行后没有发生错误,这个将会自动完成。 如果你希望能够手动删除或着释放工作,在 Illuminate\Queue\InteractsWithQueue trait 中提供 release 以及 delete 方法的接口。其中 release 方法接受单一一个值:你想要等待工作再次能够执行的秒数。 ~~~ public function handle(SendEmail $command) { if (true) { $this->release(30); } } ~~~ ## 释放一个工作回到队列中 假如在工作执行后发生错误,这个工作将会自动被释放回到队列之中,如此一来便能够再次尝试执行工作。工作会一直被释放回队列直到到达应用程序的尝试上限。这个上限数值可以在使用 queue:listen 或 queue:work Artisan 命令时候借由 --tries 开关来设置。 ## 检查工作执行次数 当一个工作执行后发生错误,这个工作将会自动的释放回队列当中,你可以透过 attempts 方法来检查这个工作已经被执行的次数: ~~~ if ($this->attempts() > 3) { // } ~~~ > 注意: 你的命令处理类别必须使用 Illuminate\Queue\InteractsWithQueue 这个 trait 才能够使用这个方法。