Laravel使用Queue隊列的技巧匯總
前言
Laravel 隊列為不同的后臺隊列服務(wù)提供統(tǒng)一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于關(guān)系型數(shù)據(jù)庫的隊列。隊列的目的是將耗時的任務(wù)延時處理,比如發(fā)送郵件,從而大幅度縮短 Web 請求和相應(yīng)的時間。
隊列配置文件存放在 config/queue.php 。每一種隊列驅(qū)動的配置都可以在該文件中找到,包括數(shù)據(jù)庫,Beanstalkd ,Amazon SQS,Redis,以及同步(本地使用)驅(qū)動。其中還包含了一個 null 隊列驅(qū)動用于那些放棄隊列的任務(wù)
為什么使用隊列?
一般來說使用隊列是為了:
異步
重試
也許你還有其他的理由使用隊列,但是這應(yīng)該是最基本的兩個原因。
什么情況使用隊列?
了解了為什么使用隊列,那么一般有這么幾類任務(wù)使用隊列:
耗時比較久的,比如上傳一個文件后進行一些格式的轉(zhuǎn)化等。
需要保證送達率的,比如發(fā)送短信,因為要調(diào)用別人的 api,總會有幾率失敗,那么為了保證送達,重試就必不可少了。
使用隊列的時候一定要想明白一個問題,這個任務(wù)到底是不是可以異步,如果因為異步會導(dǎo)致問題,那么就要放棄使用隊列。
驅(qū)動的必要設(shè)置
database.php
在 database.php 配置文件中對 redis 數(shù)據(jù)庫部分進行配置,默認有一個 default 連接,就用這個好了:)
根據(jù)這個默認連接中需要的配置項,編輯 .env 配置文件,將其中的 REDIS_HOST、REDIS_PASSWORD、REDIS_PORT 填寫成自己服務(wù)器中 Redis 的相應(yīng)值。
queue.php
首先需要去 .env 中配置 QUEUE_DRIVER,因為現(xiàn)在打算用 Redis,所以配置成 redis。
接著配置 queue.php 里 connections 部分的 redis 連接,其中 connection 對應(yīng)的值就是 database.php 中 redis 的那個 default 連接。
數(shù)據(jù)庫
要使用 database 這個隊列驅(qū)動的話,你需要創(chuàng)建一個數(shù)據(jù)表來存儲任務(wù)。你可以用 queue:table 這個 Artisan
php artisan queue:table
處理失敗的任務(wù)
有時候你隊列中的任務(wù)會失敗。不要擔(dān)心,本來事情就不會一帆風(fēng)順。
Laravel 內(nèi)置了一個方便的方式來指定任務(wù)重試的最大次數(shù)。當(dāng)任務(wù)超出這個重試次數(shù)后,它就會被插入到 failed_jobs 數(shù)據(jù)表里面。要創(chuàng)建 failed_jobs 表的遷移文件,你可以用 queue:failed-table 命令,接著使用 migrate Artisan 命令生成 failed_jobs 表:
php artisan queue:failed-table
命令來創(chuàng)建這個數(shù)據(jù)表的遷移。當(dāng)遷移創(chuàng)建好以后,就可以用 migrate 這條命令來創(chuàng)建數(shù)據(jù)表:
php artisan migrate
執(zhí)行命令講解
php artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3
--daemon
The queue:work Artisan command includes a --daemon option for forcing the queue worker to continue processing jobs without ever re-booting the framework. This results in a significant reduction of CPU usage when compared to the queue:listen command
總體來說,在 supervisor 中一般要加這個 option,可以節(jié)省 CPU 使用。
--quiet
不輸出任何內(nèi)容
--delay=3
一個任務(wù)失敗后,延遲多長時間后再重試,單位是秒。這個值的設(shè)定我個人建議不要太短,因為一個任務(wù)失?。ū热缇W(wǎng)絡(luò)原因),重試時間太短可能會出現(xiàn)連續(xù)失敗的情況。
--sleep=3
去 Redis 中拿任務(wù)的時候,發(fā)現(xiàn)沒有任務(wù),休息多長時間,單位是秒。這個值的設(shè)定要看你的任務(wù)是否緊急,如果是那種非常緊急的任務(wù),不能等待太長時間。
--tries=3
定義失敗任務(wù)最多重試次數(shù)。這個值的設(shè)定根據(jù)任務(wù)的重要程度來確定,一般 3 次比較適合。
創(chuàng)建任務(wù)
生成任務(wù)類
在你的應(yīng)用程序中,隊列的任務(wù)類都默認放在 app/Jobs 目錄下。如果這個目錄不存在,那當(dāng)你運行 make:job Artisan 命令時目錄就會被自動創(chuàng)建。你可以用以下的 Artisan 命令來生成一個新的隊列任務(wù):
php artisan make:job Demo
生成的類實現(xiàn)了 Illuminate\Contracts\Queue\ShouldQueue 接口,這意味著這個任務(wù)將會被推送到隊列中,而不是同步執(zhí)行。
<?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; use Illuminate\Support\Facades\Log; class Demo implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public $param; /** * Create a new job instance. * * @return void */ public function __construct($param = '') { $this->param = $param; } /** * Execute the job. * * @return void */ public function handle() { Log::info('Hello, '.$this->param); } }
控制器代碼
public function queue_demo() { $num = rand(1,999999999); // 這個任務(wù)將被分發(fā)到默認隊列... DemoJob::dispatch($num); }
開啟隊列
php artisan queue:work --queue=default
由于是本地,需要打開監(jiān)聽,當(dāng)訪問到接口時,就會觸發(fā)隊列中的任務(wù)
線上的話需要用到supervisor的配置
Supervisor 配置
安裝 Supervisor
Supervisor 是一個 Linux 操作系統(tǒng)上的進程監(jiān)控軟件,它會在 queue:listen 或 queue:work 命令發(fā)生失敗后自動重啟它們。在 Ubuntu 安裝 Supervisor,可以用以下命令:
sudo apt-get install supervisor
{tip} 如果自己手動配置 Supervisor 聽起來有點難以應(yīng)付,可以考慮使用 Laravel Forge,它能給你的 Laravel 項目自動安裝與配置 Supervisor。
配置 Supervisor
Supervisor 的配置文件一般是放在 /etc/supervisor/conf.d 目錄下。在這個目錄中你可以創(chuàng)建任意數(shù)量的配置文件來要求 Supervisor 怎樣監(jiān)控你的進程。例如我們創(chuàng)建一個 laravel-worker.conf 來啟動與監(jiān)控一個 queue:work 進程:
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 autostart=true autorestart=true user=forge numprocs=8 redirect_stderr=true stdout_logfile=/home/forge/app.com/worker.log
這個例子里的 numprocs 命令會要求 Supervisor 運行并監(jiān)控 8 個 queue:work 進程,并且在它們運行失敗后重新啟動。當(dāng)然,你必須更改 command 命令的 queue:work sqs ,以顯示你所選擇的隊列驅(qū)動。
啟動 Supervisor 當(dāng)這個配置文件被創(chuàng)建后,你需要更新 Supervisor 的配置,并用以下命令來啟動該進程:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:*
更多有關(guān) Supervisor 的設(shè)置與使用,請參考 Supervisor 官方文檔
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
thinkPHP多域名情況下使用memcache方式共享session數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了thinkPHP多域名情況下使用memcache方式共享session數(shù)據(jù)的實現(xiàn)方法,較為詳細的分析了session的原理及多服務(wù)器共享session的相關(guān)技巧,需要的朋友可以參考下2016-07-07使用PHP+AJAX讓W(xué)ordPress動態(tài)加載文章的教程
這篇文章主要介紹了使用PHP+AJAX讓W(xué)ordPress動態(tài)加載文章的教程,即不用手動刷新瀏覽器頁面即可讓加載好的文章顯示,需要的朋友可以參考下2015-12-12PHP命名空間(namespace)的動態(tài)訪問及使用技巧
上篇文章介紹了PHP命名空間的一些術(shù)語,其解析規(guī)則,本文我們來繼續(xù)講述PHP命名空間動態(tài)訪問及使用技巧,希望能有所幫助2014-08-08Yii2框架中使用PHPExcel導(dǎo)出Excel文件的示例
本篇文章主要介紹了Yii2框架中使用PHPExcel導(dǎo)出Excel文件的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08Laravel jwt 多表(多用戶端)驗證隔離的實現(xiàn)
這篇文章主要介紹了Laravel jwt 多表(多用戶端)驗證隔離的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12