基于Yii2的redis邮件队列

背景知识:

  1. 传统的邮件发送模式:将用户的邮件发送给第三方邮件服务器(例如网易邮箱等等),邮箱服务器再将邮件发送给指定地址,本地的web服务器则同步等待第三方邮件服务器的发送结果。从上述流程也可以看出,如果网络比较差的话,用户的操作会被阻塞直到第三方服务器返回结果。
  2. 基于redis的邮件队列:将用户的邮件存入redis队列中并直接将结果返回给用户告诉用户邮件已经发送,同时服务器端离线监听内存队列,依次将队列中的邮件进行发送,达到异步。
  3. 本文的队列是基于redis的,因此需要安装php的redis扩展,具体如何安装,可以查看我的这篇博客:传送门

1.首先安装redis服务,这里主要介绍linux下redis的安装:

wget http://download.redis.io/releases/redis-3.0.7.tar.gz
tar -xzf redis-3.0.7.tar.gz
ln -s redis-3.0.7 redis
cd redis
make && make install

2.安装好了redis之后,我们在redis目录下新建config目录,并新建一个叫做redis-6379.conf配置文件,配置项如下:

#守护进程的方式
daemonize yes  

pidfile /var/run/redis-6379.pid  

#设置端口
port 6379

#设置任意ip可访问redis服务
bind 0.0.0.0

#日志文件
logfile "redis-6379.log"



#为了测试所以才精简了配置项,在生产环境下需要谨慎配置!

3.启动redis服务:


#启动方式:redis-server+配置文件
redis-server config/redis-6379.conf

4.安装yii2的redis扩展,github主页,安装命令如下:

#全局安装
php composer.phar require --prefer-dist yiisoft/yii2-redis:"~2.0.0"

#局部安装
composer require --prefer-dist yiisoft/yii2-redis:"~2.0.0"


#并在yii的web.php中的components添加如下配置:
'redis' => [
    'class' => 'yii\redis\Connection',
    'hostname' => '119.23.70.61',  #redis服务所在服务器地址
    'port' => 6379, #端口
    'database' => 0,    #默认数据库是0号,redis默认开始了16个数据库,从0-15
],

5.由于我已经基于yii2原来的邮件类swiftmailer进行了封装,实现了基于redis的邮件队列(只支持html和text类型的邮件内容,暂不支持附件),因此读者可以直接安装扩展:

#安装扩展
composer require wxsatellite/queue-mailer


#在web.php中的components添加如下配置:
'mailer' => [
    'class' => 'sanjin\queue\Mailer',
    'db'=>1,  #选择redis的1号数据库作为邮件队列
    'key'=>'mailers',  #邮件队列的key
    'transport' => [
        'class' => 'Swift_SmtpTransport',
        'host' => 'smtp.163.com',
        'username' => '你的账号',
        'password' => '你的密码',
        'port' => '465',
        'encryption' => 'ssl',
     ],
],

6.使用方式如下:

$mailer = \Yii::$app->mailer->compose('seekpassword',['token'=>$token,'url'=>'login/change-password']);
$mailer->setFrom('[email protected]');
$mailer->setTo($this->email);
$mailer->setSubject('重置密码邮件');
try{
    if(!$mailer->pushMailToRedis()){
        //发送失败
    }
    //返送成功
}catch(\Exception $e){
    //发送失败
}


#以上代码是一个小例子仅供参考,注意不再是$mailer->send()而是$mailer->pushMailToRedis()


7.这时候我们登录redis服务器查看,可以发现redis的1号数据库中已经存在我们要发送的邮件:

8.接下来我们编写离线脚本,首先在yii的console.php配置文件中增加如下配置:


#在components配置项中增加
'redis' => [
    'class' => 'yii\redis\Connection',
    'hostname' => '119.23.70.61',
    'port' => 6379,
    'database' => 0,
],
'mailer' => [
    'class' => 'sanjin\queue\Mailer',
    'db'=>1,
    'key'=>'mailers',
    'transport' => [
        'class' => 'Swift_SmtpTransport',
        'host' => 'smtp.163.com',
        'username' => '你的账号',
        'password' => '你的密码',
        'port' => '465',
        'encryption' => 'ssl',
       ],
],

9.在commands目录下新建MailerController控制器,具体代码如下:

<?php


namespace app\commands;

use yii\console\Controller;


class MailerController extends Controller{

    public function actionSend(){
        return \Yii::$app->mailer->sendMailFromRedis();
    }
}


10.在应用程序的根目录执行如下命令,即可从队列中取出一份邮件进行发送:

./yii mailer/send

#注意,配合crontab使用效果更佳哦

以上就是redis邮件队列的使用。

猜你喜欢

转载自blog.csdn.net/wx145/article/details/83833534