laravel mysql实现队列

1 迁移需要的数据表

配置

修改.env文件,队列支持"sync", "database", "beanstalkd", "sqs", "redis", "null",这里采用数据库,其他处理方式也都一样。


# mysql数据库
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=root

# 队列驱动
QUEUE_DRIVER=database

执行

# 创建队列作业的表
php artisan queue:table
# 迁移数据
php artisan migrate

2 创建任务类

php artisan make:job SendEmail

生成文件app/Jobs/SendEmail.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}

handle 方法为队列处理的具体逻辑,我们这里添加一行日志记录

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $email;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($email)
    {
        $this->email=$email;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        \Log::info("发送邮件到 -> ".$this->email);
    }
}

3 推送任务

Controller

<?php

namespace App\Http\Controllers;

use App\Jobs\SendEmail;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function index(){
        dispatch(new SendEmail('xxxx@demo.com'));
        $this->dispatch(new SendEmail('yyyy@demo.com'));
    }
}

route

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/index','Controller@index');

推送

curl http://localhost:8084/index

查看jobs表

image.png

4 执行任务

$ php artisan queue:listen
[2019-03-15 04:39:24] Processing: App\Jobs\SendEmail
[2019-03-15 04:39:24] Processed:  App\Jobs\SendEmail
[2019-03-15 04:39:24] Processing: App\Jobs\SendEmail
[2019-03-15 04:39:24] Processed:  App\Jobs\SendEmail

查看jobs表,发现任务已经执行完成


image.png

指定最大尝试次数和超时时间

$ php artisan queue:listen --tries=3 --timeout=30``

也可以写到代码里

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * 任务最大尝试次数。
     *
     * @var int
     */
    public $tries = 3;

    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 120;


    protected $email;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($email)
    {
        $this->email=$email;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //throw  new \Exception("发生异常");
        /*
        \Mail::raw("队列测试",function ($message){
            $message->to($this->email);
        });
        */
        \Log::info("发送邮件到 -> ".$this->email);
    }
}

5 处理失败任务

有时候你队列中的任务会失败。不要担心,本来事情就不会一帆风顺。Laravel 内置了一个方便的方式来指定任务重试的最大次数。当任务超出这个重试次数后,它就会被插入到 failed_jobs 数据表里面。要创建 failed_jobs 表的迁移文件,你可以用 queue:failed-table 命令,接着使用 migrate Artisan 命令生成 failed_jobs 表

# 创建队列作业的表
php artisan queue:failed-table
# 迁移数据
php artisan migrate

查看所有失败任务 php artisan queue:failed

  • ID 任务的 ID (任务 ID 可以被用在重试失败的任务上)
  • Connection 连接
  • Queue 队列
  • Failed At 失败时间
image.png

6 失败任务重试

重试ID 为 24的失败任务,此时会将任务重新放入队列,生成新的ID

$ php artisan queue:retry 24
The failed job [24] has been pushed back onto the queue!

重试所有失败的任务使用 all 作为 ID:

 $ php artisan queue:retry all
The failed job [23] has been pushed back onto the queue!
The failed job [22] has been pushed back onto the queue!
The failed job [21] has been pushed back onto the queue!
The failed job [20] has been pushed back onto the queue!
The failed job [19] has been pushed back onto the queue!
The failed job [18] has been pushed back onto the queue!
The failed job [17] has been pushed back onto the queue!
The failed job [16] has been pushed back onto the queue!
The failed job [15] has been pushed back onto the queue!
The failed job [14] has been pushed back onto the queue!
The failed job [13] has been pushed back onto the queue!
The failed job [12] has been pushed back onto the queue!
The failed job [11] has been pushed back onto the queue!
The failed job [10] has been pushed back onto the queue!
The failed job [9] has been pushed back onto the queue!
The failed job [8] has been pushed back onto the queue!
The failed job [7] has been pushed back onto the queue!
The failed job [6] has been pushed back onto the queue!
The failed job [5] has been pushed back onto the queue!
The failed job [4] has been pushed back onto the queue!
The failed job [3] has been pushed back onto the queue!
The failed job [2] has been pushed back onto the queue!
The failed job [1] has been pushed back onto the queue!

6 失败任务删除

删除ID为74的任务

php artisan queue:forget 74

image.png

删除所有失败的任务
php artisan queue:flush

image.png

命令

queue:failed         列出所有失败的队列
queue:failed-table   创建失败队列数据表迁移
queue:flush          清除所有失败的队列作业
queue:forget         删除失败的队列作业
queue:listen        监听队列
queue:restart        重新启动队列工作进程
queue:retry         重试失败的队列
queue:table          创建队列数据库表迁移
queue:work           作为守护程序开始处理队列上的作业

queue:listen和queue:work 区别

  • queue:work - 这是新的“守护进程”进程(不再需要该标志)。该框架将启动“一次” - 然后继续循环工作。这将无限期地继续下去。它使用较少的内存/ CPU,queue:listen因为框架在整个时间内保持不变。您还必须记住使用queue:restart强制队列来更新在修补期间推送的任何代码更改。
  • queue:work --once - 这将激活框架,处理一个作业,然后关闭。适用于开发过程中的测试等
  • queue:listen - 这将在每个周期启动框架,处理一个作业,然后完全关闭,然后再次启动框架等,并无限循环。这意味着在处理每个作业后释放所有内存/进程。如果你有内存泄漏queue:work- 尝试一下。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容