Laravel源碼分析 - Redis延遲隊列(一)

延遲隊列,首先它是一個隊列。然后其任務可以延遲被執行。
實現隊列,以及延遲隊列的方式有很多種,基于Redis的方式也是比較常見,并且實現方式也比較簡單。
通過三篇文章,分析基于Laravel框架實現Redis的延遲隊列
第一篇: 依據官網介紹,實現一個簡單的Redis延遲隊列
第二篇:添加隊列任務的源碼分析
第三篇:監聽隊列的源碼分析,即消費的源碼分析

依據官網介紹,實現一個簡單的Redis延遲隊列功能

確保當前已經部署好運行Laravel5.8版本的lnmp以及redis環境,根據官網內容,配置并創建一個基于Redis的延遲隊列

1. 配置.env文件

省略其他配置,這里配置Redis的host,password,port為自己的配置,暫時添加一個REDIS_PREFIX=為空

REDIS_HOST=172.17.0.4
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_PREFIX=

QUEUE_CONNECTION=redis # 指定queue的默認服務為redis

config/queue.php配置隊列

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 90,
            'block_for' => null,
        ],

ps:默認當前已啟動Redis服務

2. 創建一個Job任務

通過artisan命令創建一個SendEmailJob.php腳本命令:php artisan make:job SendEmailJob
執行完成之后,會在app/Jobs目錄下,創建一個SendEmailJob.php腳本
修改腳本app/Jobs/SendEmailJob.php如下:

<?php

namespace App\Jobs;

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

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public function __construct()
    {
        //
    }
    public function handle()
    {
        $nowStr = Carbon::now()->toDateTimeString();
        $res = sprintf('Successful email delivery: %s', $nowStr);
        echo $res;
    }
}
3. 創建控制器

通過artisan命令創建一個控制器:php artisan make:controller Blog/QueueController
修改app/Http/Controllers/Blog/QueueController.php代碼如下:

<?php

namespace App\Http\Controllers\Blog;

use App\Jobs\SendEmailJob;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class QueueController extends Controller
{
    public function send(Request $request)
    {
        $nowStr = Carbon::now()->toDateTimeString();
        $res = sprintf('Starting email delivery: %s', $nowStr);
        SendEmailJob::dispatch()->delay(now()->addSeconds(20));
        dd($res);
    }
}

send方法就是延遲20s執行SendEmailJob任務

4. 修改路由

編輯 routes/web.php代碼如下:

<?php
Route::get('/blog/send', 'Blog\QueueController@send');
5. 命令行打開一個Redis客戶端
root@9c8ee64d2bc6:/data# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>

當前Redis中,暫無任何內容

6. 監聽隊列

通過執行artisan命令:php artisan queue:work持續監聽隊列,沒有加任務參數,默認使用config/queue.php中的'default' => env('QUEUE_CONNECTION', 'sync'),已在.env中配置了QUEUE_CONNECTION為redis。

監聽隊列

7. 運行http://localhost/blog/send
執行任務

顯示當前時間為2019-10-03 10:47:12

8. 通過redis-cli查看

運行完http://localhost/blog/send](http://localhost/blog/send之后,查看redis中存在一個key為queues:default:delayed的zset類型的數據,值為SendEmailJob對象序列化后的值

SendEmailJob對象序列化

score的值為延遲后的時間戳1570070852,日期格式為2019-10-03 10:47:32

9. 查看任務隊列的監聽
20s之后執行

顯示當前執行時間為2019-10-03 10:47:33,忽略其他耗時~

10. 再次通過redis-cli查看reds的內容
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>

可見,之前的任務已被消費,并從redis中刪除

至此,已經實現了一個基于Redis的延遲隊列,有任何問題或建議,歡迎評論~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容