延遲隊列,首先它是一個隊列。然后其任務可以延遲被執行。
實現隊列,以及延遲隊列的方式有很多種,基于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對象序列化后的值
score的值為延遲后的時間戳1570070852,日期格式為2019-10-03 10:47:32
9. 查看任務隊列的監聽
顯示當前執行時間為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的延遲隊列,有任何問題或建議,歡迎評論~