Laravel 隊列爲不一樣的後臺隊列服務提供統一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其餘基於關係型數據庫的隊列。隊列的目的是將耗時的任務延時處理,好比發送郵件,從而大幅度縮短 Web 請求和相應的時間。php
隊列配置文件存放在 config/queue.php 。每一種隊列驅動的配置均可以在該文件中找到,包括數據庫,Beanstalkd ,Amazon SQS,Redis,以及同步(本地使用)驅動。其中還包含了一個 null 隊列驅動用於那些放棄隊列的任務html
通常來講使用隊列是爲了:laravel
異步
重試
複製代碼
也許你還有其餘的理由使用隊列,可是這應該是最基本的兩個緣由。git
瞭解了爲何使用隊列,那麼通常有這麼幾類任務使用隊列:github
耗時比較久的,好比上傳一個文件後進行一些格式的轉化等。 須要保證送達率的,好比發送短信,由於要調用別人的 api,總會有概率失敗,那麼爲了保證送達,重試就必不可少了。 使用隊列的時候必定要想明白一個問題,這個任務究竟是不是能夠異步,若是由於異步會致使問題,那麼就要放棄使用隊列。redis
在 database.php 配置文件中對 redis 數據庫部分進行配置,默認有一個 default 鏈接,就用這個好了:)數據庫
根據這個默認鏈接中須要的配置項,編輯 .env 配置文件,將其中的 REDIS_HOST、REDIS_PASSWORD、REDIS_PORT 填寫成本身服務器中 Redis 的相應值。api
首先須要去 .env 中配置 QUEUE_DRIVER,由於如今打算用 Redis,因此配置成 redis。bash
接着配置 queue.php 裏 connections 部分的 redis 鏈接,其中 connection 對應的值就是 database.php 中 redis 的那個 default 鏈接。服務器
要使用 database 這個隊列驅動的話,你須要建立一個數據表來存儲任務。你能夠用 queue:table 這個 Artisan
php artisan queue:table
複製代碼
有時候你隊列中的任務會失敗。不要擔憂,原本事情就不會一路順風。
Laravel 內置了一個方便的方式來指定任務重試的最大次數。當任務超出這個重試次數後,它就會被插入到 failed_jobs 數據表裏面。要建立 failed_jobs 表的遷移文件,你能夠用 queue:failed-table 命令,接着使用 migrate Artisan 命令生成 failed_jobs 表:
php artisan queue:failed-table
複製代碼
命令來建立這個數據表的遷移。當遷移建立好之後,就能夠用 migrate 這條命令來建立數據表:
php artisan migrate
複製代碼
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,能夠節省 CPU 使用。
--quiet
複製代碼
不輸出任何內容
--delay=3
複製代碼
一個任務失敗後,延遲多長時間後再重試,單位是秒。這個值的設定我我的建議不要過短,由於一個任務失敗(好比網絡緣由),重試時間過短可能會出現連續失敗的狀況。
--sleep=3
複製代碼
去 Redis 中拿任務的時候,發現沒有任務,休息多長時間,單位是秒。這個值的設定要看你的任務是否緊急,若是是那種很是緊急的任務,不能等待太長時間。
--tries=3
複製代碼
定義失敗任務最多重試次數。這個值的設定根據任務的重要程度來肯定,通常 3 次比較適合。
在你的應用程序中,隊列的任務類都默認放在 app/Jobs 目錄下。若是這個目錄不存在,那當你運行 make:job Artisan 命令時目錄就會被自動建立。你能夠用如下的 Artisan 命令來生成一個新的隊列任務:
php artisan make:job Demo
複製代碼
生成的類實現了 Illuminate\Contracts\Queue\ShouldQueue 接口,這意味着這個任務將會被推送到隊列中,而不是同步執行。
<?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);
// 這個任務將被分發到默認隊列...
DemoJob::dispatch($num);
}
複製代碼
php artisan queue:work --queue=default
複製代碼
因爲是本地,須要打開監聽,當訪問到接口時,就會觸發隊列中的任務
線上的話須要用到supervisor的配置
Supervisor 是一個 Linux 操做系統上的進程監控軟件,它會在 queue:listen 或 queue:work 命令發生失敗後自動重啓它們。在 Ubuntu 安裝 Supervisor,能夠用如下命令:
sudo apt-get install supervisor
複製代碼
{tip} 若是本身手動配置 Supervisor 聽起來有點難以應付,能夠考慮使用 Laravel Forge,它能給你的 Laravel 項目自動安裝與配置 Supervisor。
Supervisor 的配置文件通常是放在 /etc/supervisor/conf.d 目錄下。在這個目錄中你能夠建立任意數量的配置文件來要求 Supervisor 怎樣監控你的進程。例如咱們建立一個 laravel-worker.conf 來啓動與監控一個 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 運行並監控 8 個 queue:work 進程,而且在它們運行失敗後從新啓動。固然,你必須更改 command 命令的 queue:work sqs ,以顯示你所選擇的隊列驅動。
啓動 Supervisor 當這個配置文件被建立後,你須要更新 Supervisor 的配置,並用如下命令來啓動該進程:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
複製代碼
更多有關 Supervisor 的設置與使用,請參考 Supervisor 官方文檔