Laravel使用Queue隊(duì)列的技巧匯總
前言
Laravel 隊(duì)列為不同的后臺(tái)隊(duì)列服務(wù)提供統(tǒng)一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于關(guān)系型數(shù)據(jù)庫(kù)的隊(duì)列。隊(duì)列的目的是將耗時(shí)的任務(wù)延時(shí)處理,比如發(fā)送郵件,從而大幅度縮短 Web 請(qǐng)求和相應(yīng)的時(shí)間。
隊(duì)列配置文件存放在 config/queue.php 。每一種隊(duì)列驅(qū)動(dòng)的配置都可以在該文件中找到,包括數(shù)據(jù)庫(kù),Beanstalkd ,Amazon SQS,Redis,以及同步(本地使用)驅(qū)動(dòng)。其中還包含了一個(gè) null 隊(duì)列驅(qū)動(dòng)用于那些放棄隊(duì)列的任務(wù)
為什么使用隊(duì)列?
一般來(lái)說(shuō)使用隊(duì)列是為了:
異步
重試
也許你還有其他的理由使用隊(duì)列,但是這應(yīng)該是最基本的兩個(gè)原因。
什么情況使用隊(duì)列?
了解了為什么使用隊(duì)列,那么一般有這么幾類(lèi)任務(wù)使用隊(duì)列:
耗時(shí)比較久的,比如上傳一個(gè)文件后進(jìn)行一些格式的轉(zhuǎn)化等。
需要保證送達(dá)率的,比如發(fā)送短信,因?yàn)橐{(diào)用別人的 api,總會(huì)有幾率失敗,那么為了保證送達(dá),重試就必不可少了。
使用隊(duì)列的時(shí)候一定要想明白一個(gè)問(wèn)題,這個(gè)任務(wù)到底是不是可以異步,如果因?yàn)楫惒綍?huì)導(dǎo)致問(wèn)題,那么就要放棄使用隊(duì)列。
驅(qū)動(dòng)的必要設(shè)置
database.php
在 database.php 配置文件中對(duì) redis 數(shù)據(jù)庫(kù)部分進(jìn)行配置,默認(rèn)有一個(gè) default 連接,就用這個(gè)好了:)
根據(jù)這個(gè)默認(rèn)連接中需要的配置項(xiàng),編輯 .env 配置文件,將其中的 REDIS_HOST、REDIS_PASSWORD、REDIS_PORT 填寫(xiě)成自己服務(wù)器中 Redis 的相應(yīng)值。
queue.php
首先需要去 .env 中配置 QUEUE_DRIVER,因?yàn)楝F(xiàn)在打算用 Redis,所以配置成 redis。
接著配置 queue.php 里 connections 部分的 redis 連接,其中 connection 對(duì)應(yīng)的值就是 database.php 中 redis 的那個(gè) default 連接。
數(shù)據(jù)庫(kù)
要使用 database 這個(gè)隊(duì)列驅(qū)動(dòng)的話(huà),你需要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)表來(lái)存儲(chǔ)任務(wù)。你可以用 queue:table 這個(gè) Artisan
php artisan queue:table
處理失敗的任務(wù)
有時(shí)候你隊(duì)列中的任務(wù)會(huì)失敗。不要擔(dān)心,本來(lái)事情就不會(huì)一帆風(fēng)順。
Laravel 內(nèi)置了一個(gè)方便的方式來(lái)指定任務(wù)重試的最大次數(shù)。當(dāng)任務(wù)超出這個(gè)重試次數(shù)后,它就會(huì)被插入到 failed_jobs 數(shù)據(jù)表里面。要?jiǎng)?chuàng)建 failed_jobs 表的遷移文件,你可以用 queue:failed-table 命令,接著使用 migrate Artisan 命令生成 failed_jobs 表:
php artisan queue:failed-table
命令來(lái)創(chuàng)建這個(gè)數(shù)據(jù)表的遷移。當(dāng)遷移創(chuàng)建好以后,就可以用 migrate 這條命令來(lái)創(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
總體來(lái)說(shuō),在 supervisor 中一般要加這個(gè) option,可以節(jié)省 CPU 使用。
--quiet
不輸出任何內(nèi)容
--delay=3
一個(gè)任務(wù)失敗后,延遲多長(zhǎng)時(shí)間后再重試,單位是秒。這個(gè)值的設(shè)定我個(gè)人建議不要太短,因?yàn)橐粋€(gè)任務(wù)失敗(比如網(wǎng)絡(luò)原因),重試時(shí)間太短可能會(huì)出現(xiàn)連續(xù)失敗的情況。
--sleep=3
去 Redis 中拿任務(wù)的時(shí)候,發(fā)現(xiàn)沒(méi)有任務(wù),休息多長(zhǎng)時(shí)間,單位是秒。這個(gè)值的設(shè)定要看你的任務(wù)是否緊急,如果是那種非常緊急的任務(wù),不能等待太長(zhǎng)時(shí)間。
--tries=3
定義失敗任務(wù)最多重試次數(shù)。這個(gè)值的設(shè)定根據(jù)任務(wù)的重要程度來(lái)確定,一般 3 次比較適合。
創(chuàng)建任務(wù)
生成任務(wù)類(lèi)
在你的應(yīng)用程序中,隊(duì)列的任務(wù)類(lèi)都默認(rèn)放在 app/Jobs 目錄下。如果這個(gè)目錄不存在,那當(dāng)你運(yùn)行 make:job Artisan 命令時(shí)目錄就會(huì)被自動(dòng)創(chuàng)建。你可以用以下的 Artisan 命令來(lái)生成一個(gè)新的隊(duì)列任務(wù):
php artisan make:job Demo
生成的類(lèi)實(shí)現(xiàn)了 Illuminate\Contracts\Queue\ShouldQueue 接口,這意味著這個(gè)任務(wù)將會(huì)被推送到隊(duì)列中,而不是同步執(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);
// 這個(gè)任務(wù)將被分發(fā)到默認(rèn)隊(duì)列...
DemoJob::dispatch($num);
}
開(kāi)啟隊(duì)列
php artisan queue:work --queue=default
由于是本地,需要打開(kāi)監(jiān)聽(tīng),當(dāng)訪(fǎng)問(wèn)到接口時(shí),就會(huì)觸發(fā)隊(duì)列中的任務(wù)
線(xiàn)上的話(huà)需要用到supervisor的配置
Supervisor 配置
安裝 Supervisor
Supervisor 是一個(gè) Linux 操作系統(tǒng)上的進(jìn)程監(jiān)控軟件,它會(huì)在 queue:listen 或 queue:work 命令發(fā)生失敗后自動(dòng)重啟它們。在 Ubuntu 安裝 Supervisor,可以用以下命令:
sudo apt-get install supervisor
{tip} 如果自己手動(dòng)配置 Supervisor 聽(tīng)起來(lái)有點(diǎn)難以應(yīng)付,可以考慮使用 Laravel Forge,它能給你的 Laravel 項(xiàng)目自動(dòng)安裝與配置 Supervisor。
配置 Supervisor
Supervisor 的配置文件一般是放在 /etc/supervisor/conf.d 目錄下。在這個(gè)目錄中你可以創(chuàng)建任意數(shù)量的配置文件來(lái)要求 Supervisor 怎樣監(jiān)控你的進(jìn)程。例如我們創(chuàng)建一個(gè) laravel-worker.conf 來(lái)啟動(dòng)與監(jiān)控一個(gè) queue:work 進(jìn)程:
[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
這個(gè)例子里的 numprocs 命令會(huì)要求 Supervisor 運(yùn)行并監(jiān)控 8 個(gè) queue:work 進(jìn)程,并且在它們運(yùn)行失敗后重新啟動(dòng)。當(dāng)然,你必須更改 command 命令的 queue:work sqs ,以顯示你所選擇的隊(duì)列驅(qū)動(dòng)。
啟動(dòng) Supervisor 當(dāng)這個(gè)配置文件被創(chuàng)建后,你需要更新 Supervisor 的配置,并用以下命令來(lái)啟動(dòng)該進(jìn)程:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:*
更多有關(guān) Supervisor 的設(shè)置與使用,請(qǐng)參考 Supervisor 官方文檔
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
PHP代碼判斷設(shè)備是手機(jī)還是平板電腦(兩種方法)
隨著互聯(lián)網(wǎng)移動(dòng)設(shè)備的普及,很多網(wǎng)站都兼容手機(jī)端瀏覽,為了更好的讓網(wǎng)頁(yè)在手機(jī)端顯示,我們都選擇了使用CSS媒體查詢(xún)制作響應(yīng)式模版。本文給大家介紹PHP代碼判斷設(shè)備是手機(jī)還是平板電腦(兩種方法),感興趣的朋友一起學(xué)習(xí)吧2015-10-10
Django中通過(guò)定時(shí)任務(wù)觸發(fā)頁(yè)面靜態(tài)化的處理方式
Django是一個(gè)開(kāi)放源代碼的Web應(yīng)用框架,由Python寫(xiě)成。這篇文章主要介紹了Django中通過(guò)定時(shí)任務(wù)觸發(fā)頁(yè)面靜態(tài)化的方式,需要的朋友可以參考下2018-08-08
PHP中迭代器的簡(jiǎn)單實(shí)現(xiàn)及Yii框架中的迭代器實(shí)現(xiàn)方法示例
這篇文章主要介紹了PHP中迭代器的簡(jiǎn)單實(shí)現(xiàn)及Yii框架中的迭代器實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了迭代器的原理及PHP與Yii框架中的迭代器的實(shí)現(xiàn)方法,需要的朋友可以參考下2020-04-04
Zend Framework入門(mén)之環(huán)境配置及第一個(gè)Hello World示例(附demo源碼下載)
這篇文章主要介紹了Zend Framework入門(mén)之環(huán)境配置及第一個(gè)Hello World示例,詳細(xì)講述了Zend Framework環(huán)境搭建與配置,以及實(shí)現(xiàn)第一個(gè)Hello World程序的方法,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2016-03-03
phpStudy配置多站點(diǎn)多域名方法及遇到的403錯(cuò)誤解決方法
這篇文章主要介紹了phpStudy配置多站點(diǎn)多域名方法及遇到的403錯(cuò)誤解決方法,需要的朋友可以參考下2017-10-10

