Laravel进阶系列笔记--(七)Laravel 基础数据库存储的消息队列的使用

作者: 温新

分类: 【Laravel】

阅读: 2018

时间: 2021-08-16 13:43:17

作者:温新

时间:2021-07-08

hi,我是温新,一名PHPer。

基于数据库驱动的消息队列

第一步:修改驱动为数据库驱动

文件:.env

QUEUE_CONNECTION=database

第二步:创建任务信息表

1)创建迁移文件

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 消息队列任务迁移文件</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">queue</span>:<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 消息队列任务失败迁移文件</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">queue</span>:<span style="box-sizing: border-box;color: rgb(0, 0, 0)">failed</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span></span>

2)执行迁移文件

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">migrate</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">--</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">path</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">database</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">/</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">migrations</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">/</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">_07_08_145208_create_jobs_table</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">migrate</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">--</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">path</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">database</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">/</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">migrations</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">/</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">_07_08_145604_create_failed_jobs_table</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span>

为了便于理解字段的含义,我为这两个迁移文件添加了备注,字段的含义还是有必要了解一下的。

这两个迁移文件后后可直接执行 php artisan migrate

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 2021_07_08_145208_create_jobs_table.php 队列任务表</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Schema</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">create</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'jobs'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> (<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Blueprint</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">bigIncrements</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'id'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">string</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'queue'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">index</span>()<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列名'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">longText</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'payload'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列处理信息'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unsignedTinyInteger</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'attempts'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列执行次数'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unsignedInteger</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'reserved_at'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">nullable</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unsignedInteger</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'available_at'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unsignedInteger</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'created_at'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 2021_07_08_145604_create_failed_jobs_table.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 队列执行失败记录表</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Schema</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">create</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'failed_jobs'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> (<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Blueprint</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">id</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">string</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'uuid'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unique</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">text</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'connection'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'连接'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">text</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'queue'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">longText</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'payload'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列任务'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">longText</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'exception'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'异常'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">timestamp</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'failed_at'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">useCurrent</span>()<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'队列失败时间'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>

第三步:创建任务类

php artisan make:job SendEamilToUser

该命令会在app/Jobs目录下生成SendEamilToUser.php文件。

编辑SendEamilToUser.php文件进行消息队列任务的处理

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">namespace</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">App\Jobs</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Models\User</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Bus\Queueable</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Queue\ShouldBeUnique</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Queue\ShouldQueue</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Foundation\Bus\Dispatchable</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Queue\InteractsWithQueue</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Queue\SerializesModels</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Support\Facades\Log</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">SendEamilToUser</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">implements</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">ShouldQueue</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Dispatchable</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">InteractsWithQueue</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Queueable</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">SerializesModels</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">null</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">User</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">handle</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 此处执行自定义任务</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Log</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">info</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'发送邮件给 【'</span> . <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">user</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">name</span> . <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'】 用户成功'</span> );</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

第四步:派发任务给队列

1)定义路由

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// web.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'queue'</span>, <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'UserController@queue'</span>);</span>

2)添加queue方法并编写任务代码

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// UserController.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Jobs\SendEamilToUser</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">queue</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$users</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">\App\Models\User</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">all</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">foreach</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$users</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">as</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 为每个用户发送消息的任务</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 方式一</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">//dispatch(new SendEamilToUser($user));</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 方式二</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 0, 0)">SendEamilToUser</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">dispatch</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'派发队列任务成功'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

打开jobs数据表就会看到相关的任务信息了。

3)访问路由添加队列任务

第五步:执行队列任务

--once执行一个队列任务

php artisan queue:work --once
// 执行后返回信息
[2021-07-08 15:41:05][1] Processing: App\Jobs\SendEamilToUser
[2021-07-08 15:41:05][1] Processed:  App\Jobs\SendEamilToUser

练习的环境中建议从执行一个开始。我这里执行--once命令。

queue:work执行所有队列任务

php artisan queue:work

第六步:查看laravel.log文件是否发送邮件成功

// laravel.log
[2021-07-08 15:41:05] local.INFO: 发送邮件给 【Dell Terry】 用户成功

处理失败的队列任务

队列中的任务有可能会失败,执行失败的任务是删除还是重新执行?

任务过期与超时

--timeout设置每个任务超时时间(s)

php artisan queue:work --timeout=60

每个任务60秒没有执行成功,那么90秒后会重新执行该任务。任务重启时间可以通过config/queue.php进行配置,如现在使用的数据库驱动,配置如下

'database' => [
    'driver' => 'database',
    'table' => 'jobs',
    'queue' => 'default',
    'retry_after' => 90, // 配置此参数,失败任务的重发时间
    'after_commit' => false,
],

失败的任务处理

第一步:修改SendEamilToUser文件模拟任务失败

// app/Jobs/SendEamilToUser.php

public function handle()
{
    // 该函数不存在,因此队列任务执行失败
    testQueue();
    // 此处执行自定义任务
    Log::info('发送邮件给 【' . $this->user->name . '】 用户成功' );
}

任务失败会后进入到failed_jobs数据表中。

第二步:处理失败的任务

// app/Jobs/SendEamilToUser.php
// 只要有队列任务执行失败,就会自动执行该方法
public function failed(\Throwable $exception)
{
    Log::error('发送给 【【' . $this->user->name . '】】的邮件失败');
}

第三步:处理failed_jobs失败的任务(根据需要来执行)

1)queue:failed查看failed_jobs所有失败的任务。该命令将会列出任务 ID、连接、队列和失败时间,任务 ID 可用于重试失败任务。

php artisan queue:failed

2)queue:retry ID重试失败的任务。

php artisan queue:retry d2111845-9d25-4d9a-b00e-67658fe1a9c7

3)queue:retry all重试所有失败的任务

php artisan queue:retry all

4)queue:forget ID删除一个失败的任务

php artisan queue:forget e81f9536-f3e0-49e2-8c38-780d7f242b19

5)queue:flush删除所有失败的任务

php artisan queue:flush

1)这里的ID指的是failed_jobs表中的UUID;

2)我这里执行的是删除所有失败的任务

任务分发

前面演示的是立即分发任务,有时间需要指定时间分发任务,Laravel中提供了相关方法。

延时分发任务

方法:delay(时间)

// app/Http/Controllers/UserController.php

public function queue()
{
    $users = \App\Models\User::all();
    foreach ($users as $user) {
        // 延迟一分钟执行。队列任务最多延时15分钟
        SendEamilToUser::dispatch($user)->delay(now()->addMinutes(1));
    }
    return '派发队列任务成功';
}

同步分发

dispatchNow()同步分发。就是任务不会写入到数据表,而是执行被执行。

public function queue()
{

    $users = \App\Models\User::all();
    foreach ($users as $user) {
        SendEamilToUser::dispatchNow($user);
    }
    return '派发队列任务成功';
}

本篇文章,未完。

我是温新

每天进步一点点,就一点点

请登录后再评论