环境:LNMP(CentOS7.2 + Nginx1.10 + MariaDB10.0 + PHP5.6),Laravel5.1;
目的:在Laravel框架上,用Beanstalkd消息队列实现异步发送邮件;
预备知识:Laravel框架基本编程;使用Laravel自带的Mail功能发送邮件;
一般来说消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式。本文讨论的通过Beanstalkd发送邮件使用的就是生产者消费者模式。在这种模式下,让我简单来介绍一下什么是消息队列,以及通过简单的程序来了解消息队列的使用。
一句话,消息队列本质上是在程序与程序之间传递数据的一种方式。
使用常见的客户端pda/pheanstalk,且在封装成单例模式类后,核心代码就这么几行:
生产者生产数据:
Beanstalk::putInTube('queue_name', 'some string');
消费者获取数据:
//这里的参数3是reserve timeout的秒数
$job = Beanstalk::reserveFromTube('queue_name', 3);
$data = $job->getData();
上面这些,让我们对Beanstalkd有了概念,以及知道了如何在普通程序下的使用它,下面让我们进入正题 ,探讨Beanstalkd在Laravel上的使用。
和Beanstalkd在普通程序下的使用不同,在Laravel里Beanstalkd消费者的数据和行为是作为一个类存在的,它们分别对应类里的属性和方法。
说得再多不如看代码。
编写任务,即上文说的Beanstalkd消费者的数据和行为,也是一个类文件,文件名app/Jobs/SendNewUserRegNotifyMail.php,内容如下:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;
/**
* 发送新用户注册的通知邮件给公司相关人员(如客服)
* @author los
*/
class SendNewUserRegNotifyMail extends Job implements SelfHandling, ShouldQueue {
protected $to_list; //收件人,示例:username<username@example.com>
protected $data; //邮件内容的数据,传递给视图的数组
/**
* 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('新用户注册通知');
});
}
}
编写任务调用的邮件模板,文件名resources/views/common/mail/new_user_reg_notify_mail.blade.php,内容如下:
昵称:{{$nickname}}<br />
联系电话:{{$mobile}}<br />
编写调用任务的程序,新用户注册时,调用发送通知邮件的任务,并把任务加入到指定队列,代码如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
/**
* Reg
* @author los_gsy
*/
class RegController extends Controller {
/**
* 构造函数
*/
public function __construct(Request $req) {
parent::__construct();
}
/**
* 处理用户注册,此时 发送新用户注册的通知邮件给公司相关人员(如客服)
* @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);
}
}
至此,异步发送邮件的队列核心代码已完成。但,队列不会自动运行,还需要有监听程序,此时,只需要在项目根目录运行如下Artisan命令即可:
php artisan queue:work beanstalkd --queue=default --sleep=1 --tries=3 --daemon
最后,在浏览器输入http://your_domain/Reg/handleReg,即可触发通知邮件发送。
本文阐述的是在Laravel上使用Beanstalkd的核心代码,以及代码里体现出来的实践经验。因此,若无基本的Laravel使用技能,可能上手还有点难度。但是,好的东西就值得学习,不是么?