Beanstalkd in Laravel
概述
環(huán)境:LNMP(CentOS7.2 + Nginx1.10 + MariaDB10.0 + PHP5.6)内边,Laravel5.1;
目的:在Laravel框架上羊壹,用Beanstalkd消息隊(duì)列實(shí)現(xiàn)異步發(fā)送郵件锋边;
預(yù)備知識(shí):Laravel框架基本編程歌馍;使用Laravel自帶的Mail功能發(fā)送郵件黍氮;
正文
一般來說消息隊(duì)列有兩種場景跛十,一種是發(fā)布者訂閱者模式彤路,一種是生產(chǎn)者消費(fèi)者模式。本文討論的通過Beanstalkd發(fā)送郵件使用的就是生產(chǎn)者消費(fèi)者模式芥映。在這種模式下洲尊,讓我簡單來介紹一下什么是消息隊(duì)列,以及通過簡單的程序來了解消息隊(duì)列的使用奈偏。
一句話坞嘀,消息隊(duì)列本質(zhì)上是在程序與程序之間傳遞數(shù)據(jù)的一種方式。
使用常見的客戶端pda/pheanstalk惊来,且在封裝成單例模式類后丽涩,核心代碼就這么幾行:
生產(chǎn)者生產(chǎn)數(shù)據(jù):
Beanstalk::putInTube('queue_name', 'some string');
消費(fèi)者獲取數(shù)據(jù):
//這里的參數(shù)3是reserve timeout的秒數(shù)
$job = Beanstalk::reserveFromTube('queue_name', 3);
$data = $job->getData();
上面這些,讓我們對(duì)Beanstalkd有了概念裁蚁,以及知道了如何在普通程序下的使用它矢渊,下面讓我們進(jìn)入正題 ,探討B(tài)eanstalkd在Laravel上的使用枉证。
和Beanstalkd在普通程序下的使用不同矮男,在Laravel里Beanstalkd消費(fèi)者的數(shù)據(jù)和行為是作為一個(gè)類存在的,它們分別對(duì)應(yīng)類里的屬性和方法刽严。
說得再多不如看代碼昂灵。
代碼
編寫任務(wù),即上文說的Beanstalkd消費(fèi)者的數(shù)據(jù)和行為舞萄,也是一個(gè)類文件眨补,文件名app/Jobs/SendNewUserRegNotifyMail.php,內(nèi)容如下:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;
/**
* 發(fā)送新用戶注冊(cè)的通知郵件給公司相關(guān)人員(如客服)
* @author los
*/
class SendNewUserRegNotifyMail extends Job implements SelfHandling, ShouldQueue {
protected $to_list; //收件人倒脓,示例:username<username@example.com>
protected $data; //郵件內(nèi)容的數(shù)據(jù)撑螺,傳遞給視圖的數(shù)組
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($to_list, $data) {
$this->to_list = $to_list;
$this->data = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle() {
Mail::send('common/mail/new_user_reg_notify_mail', $this->data, function($mail) {
foreach ($this->to_list as $v) {
$name = substr($v, 0, strpos($v, '<'));
$addr = substr($v, strpos($v, '<') + 1, -1);
$mail->to($addr, $name);
}
$mail->subject('新用戶注冊(cè)通知');
});
}
}
編寫任務(wù)調(diào)用的郵件模板,文件名resources/views/common/mail/new_user_reg_notify_mail.blade.php崎弃,內(nèi)容如下:
昵稱:{{$nickname}}<br />
聯(lián)系電話:{{$mobile}}<br />
編寫調(diào)用任務(wù)的程序甘晤,新用戶注冊(cè)時(shí)含潘,調(diào)用發(fā)送通知郵件的任務(wù),并把任務(wù)加入到指定隊(duì)列线婚,代碼如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
/**
* Reg
* @author los_gsy
*/
class RegController extends Controller {
/**
* 構(gòu)造函數(shù)
*/
public function __construct(Request $req) {
parent::__construct();
}
/**
* 處理用戶注冊(cè)遏弱,此時(shí) 發(fā)送新用戶注冊(cè)的通知郵件給公司相關(guān)人員(如客服)
* @param Request $req
*/
public function handleReg(Request $req) {
$data = ['nickname' => 'kitty', 'mobile' => '18612345678'];
$job = new SendNewUserRegNotifyMail(['los<51220269@qq.com>'], $data);
$job->onQueue(env('queue_default'));
$result = dispatch($job);
var_export($result);
}
}
至此,異步發(fā)送郵件的隊(duì)列核心代碼已完成塞弊。但漱逸,隊(duì)列不會(huì)自動(dòng)運(yùn)行,還需要有監(jiān)聽程序游沿,此時(shí)饰抒,只需要在項(xiàng)目根目錄運(yùn)行如下Artisan命令即可:
php artisan queue:work beanstalkd --queue=default --sleep=1 --tries=3 --daemon
最后,在瀏覽器輸入http://your_domain/Reg/handleReg诀黍,即可觸發(fā)通知郵件發(fā)送袋坑。
結(jié)尾
本文闡述的是在Laravel上使用Beanstalkd的核心代碼,以及代碼里體現(xiàn)出來的實(shí)踐經(jīng)驗(yàn)眯勾。因此枣宫,若無基本的Laravel使用技能,可能上手還有點(diǎn)難度咒精。但是镶柱,好的東西就值得學(xué)習(xí),不是么模叙?