延遲隊列,首先它是一個隊列。然后其任務(wù)可以延遲被執(zhí)行潮梯。
實現(xiàn)隊列骗灶,以及延遲隊列的方式有很多種,基于Redis的方式也是比較常見秉馏,并且實現(xiàn)方式也比較簡單耙旦。
通過三篇文章,分析基于Laravel框架實現(xiàn)Redis的延遲隊列
第一篇: 依據(jù)官網(wǎng)介紹萝究,實現(xiàn)一個簡單的Redis延遲隊列
第二篇:添加隊列任務(wù)的源碼分析
第三篇:監(jiān)聽隊列的源碼分析免都,即消費的源碼分析
依據(jù)官網(wǎng)介紹,實現(xiàn)一個簡單的Redis延遲隊列功能
確保當前已經(jīng)部署好運行Laravel5.8版本的lnmp以及redis環(huán)境,根據(jù)官網(wǎng)內(nèi)容,配置并創(chuàng)建一個基于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的默認服務(wù)為redis
config/queue.php
配置隊列
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
ps:默認當前已啟動Redis服務(wù)
2. 創(chuàng)建一個Job任務(wù)
通過artisan命令創(chuàng)建一個SendEmailJob.php腳本命令:php artisan make:job SendEmailJob
執(zhí)行完成之后升酣,會在app/Jobs
目錄下舷暮,創(chuàng)建一個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. 創(chuàng)建控制器
通過artisan命令創(chuàng)建一個控制器: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執(zhí)行SendEmailJob任務(wù)
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中,暫無任何內(nèi)容
6. 監(jiān)聽隊列
通過執(zhí)行artisan命令:php artisan queue:work
持續(xù)監(jiān)聽隊列噩茄,沒有加任務(wù)參數(shù)下面,默認使用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類型的數(shù)據(jù)沥割,值為SendEmailJob對象序列化后的值
score的值為延遲后的時間戳1570070852,日期格式為2019-10-03 10:47:32
9. 查看任務(wù)隊列的監(jiān)聽
顯示當前執(zhí)行時間為2019-10-03 10:47:33凿菩,忽略其他耗時~
10. 再次通過redis-cli查看reds的內(nèi)容
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
可見机杜,之前的任務(wù)已被消費,并從redis中刪除
至此衅谷,已經(jīng)實現(xiàn)了一個基于Redis的延遲隊列椒拗,有任何問題或建議,歡迎評論~