主頁 > 知識(shí)庫 > Laravel框架中隊(duì)列和工作(Queues、Jobs)操作實(shí)例詳解

Laravel框架中隊(duì)列和工作(Queues、Jobs)操作實(shí)例詳解

熱門標(biāo)簽:Mysql連接數(shù)設(shè)置 服務(wù)器配置 電子圍欄 科大訊飛語音識(shí)別系統(tǒng) Linux服務(wù)器 阿里云 團(tuán)購網(wǎng)站 銀行業(yè)務(wù)

在我們的web應(yīng)用中,經(jīng)常會(huì)遇到這樣的情況:

用戶在進(jìn)行了某項(xiàng)操作后,我們需要在后臺(tái)完成一個(gè)耗時(shí)且耗費(fèi)資源的任務(wù),以對(duì)應(yīng)用戶的操作。

通常來說,web應(yīng)用中的操作都是同步的(synchronous),即用戶的操作可以立即得到回饋。

但是在以上情況下,同步等待操作結(jié)果將是災(zāi)難性的。比如用戶點(diǎn)擊了申請(qǐng)密碼重置郵件,倘若我們讓用戶一直停滯在等待頁面,直至郵件發(fā)送成功,那么用戶體驗(yàn)將非常地不好,因?yàn)橛袝r(shí)候可能需要很長(zhǎng)的時(shí)間才能將郵件發(fā)送完成。

從另一個(gè)角度來說,如果我們服務(wù)器處于高負(fù)荷的情況,當(dāng)多個(gè)用戶同時(shí)請(qǐng)求發(fā)送郵件等操作時(shí),我們不希望同時(shí)地給服務(wù)器增加負(fù)荷,否則可能會(huì)導(dǎo)致服務(wù)器崩潰,造成無法預(yù)估的情況。

從以上的討論可以看出,我們需要一種機(jī)制,可以非同步地響應(yīng)用戶操作,并且不會(huì)給服務(wù)器增加過大的負(fù)荷。

那么這樣一種機(jī)制就是Queues和Jobs(即隊(duì)列和工作)。

如果你系統(tǒng)地學(xué)習(xí)過計(jì)算機(jī)科學(xué),那么隊(duì)列的概念你應(yīng)該不陌生。假設(shè)我們?nèi)ャy行辦事,我們拿了一個(gè)號(hào),發(fā)現(xiàn)前面有8個(gè)人在等待,那么我們實(shí)際上就處在一個(gè)隊(duì)列之中,隊(duì)列中靠前的人會(huì)先被叫到號(hào)碼,并且叫號(hào)的順序即拿號(hào)的順序。這樣的隊(duì)列就叫做Queue,采用的是先到先處理的方式,不允許插隊(duì)的情況存在。而我們要辦的事情就叫Job。

在Laravel中,我們可以很方便地使用Queues及Jobs來達(dá)到我們的目的。首先我們需要先來看一下,Laravel中有哪些Queues。

打開config/queue.php,我們可以看到幾種常見的隊(duì)列設(shè)置:

return [      
  
  /*      
  |--------------------------------------------------------------------------      
  | Default Queue Connection Name      
  |--------------------------------------------------------------------------      
  |      
  | Laravel's queue API supports an assortment of back-ends via a single      
  | API, giving you convenient access to each back-end using the same      
  | syntax for every one. Here you may define a default connection.      
  |      
  */      
  
  'default' => env('QUEUE_DRIVER', 'sync'),      
  
  /*      
  |--------------------------------------------------------------------------      
  | Queue Connections      
  |--------------------------------------------------------------------------      
  |      
  | Here you may configure the connection information for each server that      
  | is used by your application. A default configuration has been added      
  | for each back-end shipped with Laravel. You are free to add more.      
  |      
  | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"      
  |      
  */      
  
  'connections' => [      
  
    'sync' => [      
      'driver' => 'sync',      
    ],      
  
    'database' => [      
      'driver' => 'database',      
      'table' => 'jobs',      
      'queue' => 'default',      
      'retry_after' => 90,      
    ],      
  
    'beanstalkd' => [      
      'driver' => 'beanstalkd',      
      'host' => 'localhost',      
      'queue' => 'default',      
      'retry_after' => 90,      
    ],      
  
    'sqs' => [      
      'driver' => 'sqs',      
      'key' => env('SQS_KEY', 'your-public-key'),      
      'secret' => env('SQS_SECRET', 'your-secret-key'),      
      'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),      
      'queue' => env('SQS_QUEUE', 'your-queue-name'),      
      'region' => env('SQS_REGION', 'us-east-1'),      
    ],      
  
    'redis' => [      
      'driver' => 'redis',      
      'connection' => 'default',      
      'queue' => 'default',      
      'retry_after' => 90,      
      'block_for' => null,      
    ],      
  
  ],      
  
  /*      
  |--------------------------------------------------------------------------      
  | Failed Queue Jobs      
  |--------------------------------------------------------------------------      
  |      
  | These options configure the behavior of failed queue job logging so you      
  | can control which database and table are used to store the jobs that      
  | have failed. You may change them to any database / table you wish.      
  |      
  */      
  
  'failed' => [      
    'database' => env('DB_CONNECTION', 'mysql'),      
    'table' => 'failed_jobs',      
  ],      
  
];

在connections中,我們看到sync這個(gè)連接。sync是Laravel默認(rèn)的隊(duì)列,代表的就是synchronous,即同步隊(duì)列。

今天我們要來看一下,如何使用database,即數(shù)據(jù)庫來實(shí)現(xiàn)異步任務(wù)處理。

要使用database來作為隊(duì)列的內(nèi)部實(shí)現(xiàn)機(jī)制,我們需要建立一張用于儲(chǔ)存Jobs的表:

$ php artisan queue:table     
$ php artisan migrate

以上命令將會(huì)在數(shù)據(jù)庫創(chuàng)建名為jobs的表。

隊(duì)列我們有了,那么現(xiàn)在我們來看一下Jobs。Laravel中jobs文件默認(rèn)位置在app/Jobs文件夾下,我們可以通過make:job這個(gè)Artisan命令快速創(chuàng)建我們的job類:

$ php artisan make:job SendEmail

生成的job會(huì)實(shí)現(xiàn)Illuminate\Contracts\Queue\ShouldQueue這個(gè)接口,表明生成的job對(duì)象將被推到隊(duì)列中進(jìn)行異步處理。

job類其實(shí)很簡(jiǎn)單,里面只有一個(gè)名為handle的方法,該方法在job被queue處理的時(shí)候自動(dòng)被調(diào)用。

在上面的命令中,我們創(chuàng)建了一個(gè)名為SendEmail的類:

?php    
  
namespace App\Jobs;    
  
use App\Email;    
use Illuminate\Bus\Queueable;    
use Illuminate\Queue\SerializesModels;    
use Illuminate\Queue\InteractsWithQueue;    
use Illuminate\Contracts\Queue\ShouldQueue;    
use Illuminate\Foundation\Bus\Dispatchable;    
  
class SendEmail implements ShouldQueue    
{    
  use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;    
  
  protected $email;    
  
  /**    
   * Create a new job instance.    
   *    
   * @param Podcast $podcast    
   * @return void    
   */    
  public function __construct(Email $email)    
  {    
    $this->email = $email;    
  }    
  
  /**    
   * Execute the job.    
   *    
   * @param AudioProcessor $processor    
   * @return void    
   */    
  public function handle()    
  {    
    // Process email and send the email to recipient(s)    
    // 這里我們可以處理我們的郵件并將郵件發(fā)送至接收人 
  }    
}

可以看到,我們可以將model傳遞進(jìn)job的constructor中。Laravel會(huì)自動(dòng)序列化(Serialize)模型的識(shí)別信息,在job真正被處理的時(shí)候,完整的模型數(shù)據(jù)才會(huì)被從數(shù)據(jù)庫調(diào)用出來。另外,在handle方法中,我們也可以注入我們的依賴dependencies。

好了,現(xiàn)在我們有了job類,可以創(chuàng)建job對(duì)象了,那么如何把job添加進(jìn)隊(duì)列呢?

在我們的控制器中,我們可以調(diào)用job的dispatch方法來將其添加進(jìn)隊(duì)列中:

?php  
  
namespace App\Http\Controllers;  
  
use App\Jobs\SendEmail;  
use Illuminate\Http\Request;  
use App\Http\Controllers\Controller;  
use App\Email; 
  
class EmailsController extends Controller  
{  
  /**  
   * Store a new email.  
   *  
   * @param Request $request  
   * @return Response  
   */  
  public function send(Request $request)  
  {  
    // Create email...  
    // 這里我們提取email信息并創(chuàng)建$email, Email是我們自定義的Model 
    $email = Email::create($request->only('sender', 'to', 'content')); 
  
    SendEmail::dispatch($email);  
  }  
}

這樣一來,每當(dāng)我們的控制器調(diào)用send方法時(shí),就會(huì)創(chuàng)建一個(gè)SendEmail的job在數(shù)據(jù)庫中。

那么怎么樣調(diào)用Queue Worker來處理我們的jobs呢?

在.env文件中,我們將QUEUE_DRIVER=sync改為QUEUE_DRIVER=database。

接下來,我們運(yùn)行以下Artisan命令:

$ php artisan queue:work

隊(duì)列的worker會(huì)一直運(yùn)行,每當(dāng)有任務(wù)被添加進(jìn)數(shù)據(jù)庫jobs表中,worker便會(huì)自動(dòng)抓取出任務(wù)進(jìn)行處理。當(dāng)任務(wù)失敗時(shí),worker會(huì)重復(fù)執(zhí)行任務(wù),直至最大嘗試次數(shù)(默認(rèn)為255)。我們可以手動(dòng)設(shè)置最大嘗試次數(shù):

$ php artisan queue:work --tries=3

當(dāng)然,我們也可以手動(dòng)設(shè)置任務(wù)的超時(shí)(默認(rèn)90s,在config/queue.php中的retry_after設(shè)置):

$ php artisan queue:work --timeout=30

最后,當(dāng)沒有任務(wù)的時(shí)候,我們可以設(shè)置一個(gè)睡眠時(shí)間,當(dāng)worker在睡眠時(shí)間時(shí),將不會(huì)處理任務(wù):

$ php artisan queue:work --sleep=10

上面的命令意思是每當(dāng)worker處理完所有任務(wù)后,會(huì)睡眠10s,然后才會(huì)再次檢查任務(wù)隊(duì)列

本文使用Laravel 5.6進(jìn)行講解

本文主要講解了Laravel框架中隊(duì)列和工作(Queues、Jobs)操作實(shí)例詳解,更多關(guān)于Laravel框架的使用技巧請(qǐng)查看下面的相關(guān)鏈接

您可能感興趣的文章:
  • laravel5.6 框架郵件隊(duì)列database驅(qū)動(dòng)簡(jiǎn)單demo示例
  • Laravel使用Queue隊(duì)列的技巧匯總
  • Docker部署Laravel應(yīng)用實(shí)現(xiàn)隊(duì)列&任務(wù)調(diào)度
  • Laravel 6 將新增為指定隊(duì)列任務(wù)設(shè)置中間件的功能
  • Laravel 隊(duì)列使用的實(shí)現(xiàn)
  • Laravel框架隊(duì)列原理與用法分析
  • Laravel中為什么不使用blpop取隊(duì)列詳析
  • 關(guān)于 Laravel Redis 多個(gè)進(jìn)程同時(shí)取隊(duì)列問題詳解
  • 源碼分析 Laravel 重復(fù)執(zhí)行同一個(gè)隊(duì)列任務(wù)的原因
  • Laravel使用消息隊(duì)列需要注意的一些問題
  • Laravel中利用隊(duì)列發(fā)送郵件的方法示例
  • 淺談Laravel隊(duì)列實(shí)現(xiàn)原理解決問題記錄
  • 淺析Laravel5中隊(duì)列的配置及使用
  • PHP的Laravel框架中使用消息隊(duì)列queue及異步隊(duì)列的方法
  • Laravel 4.2 中隊(duì)列服務(wù)(queue)使用感受

標(biāo)簽:大理 廣元 衢州 蚌埠 衡水 棗莊 江蘇 萍鄉(xiāng)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Laravel框架中隊(duì)列和工作(Queues、Jobs)操作實(shí)例詳解》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266