资讯专栏INFORMATION COLUMN

redis的简单使用 异步发送邮件

娣辩孩 / 3439人阅读

摘要:你是否也困在,知其然不知其所以然项目中到底怎么用一个简单的实例使用消息队列实现下异步发送邮件准备工作首先得配置服务,之前写过相关的文章,可以参考下这里的操作库使用安装的依赖库的相关配置到此中就可以使用进行操作了同步与异步那么如何实现

你是否也困在redis,知其然不知其所以然~~ 项目中,到底怎么用?? 一个简单的实例,使用消息队列实现下yii异步发送邮件

redis~~准备工作:

首先得配置redis服务,之前写过相关的文章,可以参考下这里 https://segmentfault.com/a/11...

yii的redis操作库:https://github.com/yiisoft/yi...

使用composer安装redis的依赖库

php composer.phar require --prefer-dist yiisoft/yii2-redis

web.php的相关配置:

return [
    //....
    "components" => [
        "redis" => [
            "class" => "yii
edisConnection",
            "hostname" => "localhost",
            "port" => 6379,
            "database" => 0,
        ],
    ]
];

到此,yii中就可以使用redis进行操作了

redis~~同步与异步

那么如何实现异步消息队列发送邮件呢??

传统的操作方法是这样的:

用户输入邮件信息

服务器获取用户输入的数据,提交到第三方的邮件服务器

第三方邮件服务器发送邮件,返回处理结果

异步的处理邮件发送:

用户输入邮件相关信息

将注册信息存储在内存队列,通知用户发送成功

服务器端监听内存队列,将内存队列中的邮件数据依次发送 用户感知不到

两者的区别在哪?

异步相对于同步来说,页面非阻塞,减少了用户等待的时间体验相对来说比较好

redis~~邮件发送

原理:
用户输入邮件信息,服务器接收到输入的邮件信息,调用mail的过程,实则是对mail类属性赋值的过程,这个时候,我们可以抓取用户的信息,存储到队列,然后在队列中,依次读取邮件信息,进行发送

 //实例化mail组件

$mailer = Yii::$app->mailer->compose();
$mailer->setFrom("发件人地址");
$mailer->setTo("收件人地址");
$mailer->setSubject("发送标题");
//if ($mailer->send() && $this->reg($data, "regbymail")) {
//注意这里 本身是直接调用 send方法 进行发送 现在重写父类方法 使用redis进行处理 
if ($mailer->queue()) {
    return true;
}

这个时候 会去实例化mail类 进行邮件发送,这个时候 我们可以抓取邮件信息 存储到队列中

    redis;
            if (empty($redis)) {
                throw new yiiaseInvalidConfigException("redis not found in config.");
            }
            // 0 - 15  select 0 select 1
            // db => 1
            $mailer = Yii::$app->mailer;
            //mail邮件存储的数据库 是否存在
            if (empty($mailer) || !$redis->select($mailer->db)) {
                throw new yiiaseInvalidConfigException("db not defined.");
            }
            //抓取邮件信息
            $message = [];
            $message["from"] =array_keys($this->from);
            $message["to"] =  array_keys($this->getTo());
            $message["cc"] =  array_keys($this->getCc());
            $message["bcc"] = array_keys($this->getBcc());
            $message["reply_to"] = array_keys($this->getReplyTo());
            $message["charset"] = array_keys($this->getCharset());
            $message["subject"] = array_keys($this->getSubject());
            //获取邮件信息及子信息
            $parts = $this->getSwiftMessage()->getChildren();
    
            if (!is_array($parts) || !sizeof($parts)) {
                $parts = [$this->getSwiftMessage()];
            }
            foreach ($parts as $part) {
    
                if (!$part instanceof Swift_Mime_Attachment) {
                    //获取内容类型
                    switch($part->getContentType()) {
                        case "text/html":
                            $message["html_body"] = $part->getBody();
                            break;
                        case "text/plain":
                            $message["text_body"] = $part->getBody();
                            break;
                    }
                    if (!$message["charset"]) {
                        $message["charset"] = $part->getCharset();
                    }
                }
            }
            //序列化抓取的内容   存放到队列中
            
            return $redis->rpush($mailer->key, json_encode($message));
        }
    }

 接下来就是读取redis队列,进行发送的过程 
redis;
        if (empty($redis)) {
            throw new yiiaseInvalidConfigException("redis not found in config.");
        }
        //如果队列中 存在数据
        if ($redis->select($this->db) && $messages = $redis->lrange($this->key, 0, -1)) {
            $messageObj = new Message;
            //遍历邮件列表
            foreach ($messages as $message) {
                $message = json_decode($message, true);
                if (empty($message) || !$this->setMessage($messageObj, $message)) {
                    throw new ServerErrorHttpException("message error");
                }
                if ($messageObj->send()){
                    $redis->lrem($this->key, -1, json_encode($message));
                }
            }
        }
        return true;
    }

    //设置消息头部
    public function setMessage($messageObj, $message) 
    {
        if (empty($messageObj)) {
            return false;
        }
        if (!empty($message["from"]) && !empty($message["to"])) {
            $messageObj->setFrom($message["from"])->setTo($message["to"]);
            if (!empty($message["cc"])) {
                $messageObj->setCc($message["cc"]);
            }
            if (!empty($message["bcc"])) {
                $messageObj->setBcc($message["bcc"]);
            }
            if (!empty($message["reply_to"])) {
                $messageObj->setReplyTo($message["reply_to"]);
            }
            if (!empty($message["charset"])) {
                $messageObj->setCharset($message["charset"]);
            }
            if (!empty($message["subject"])) {
                $messageObj->setSubject($message["subject"]);
            }
            if (!empty($message["html_body"])) {
                $messageObj->setHtmlBody($message["html_body"]);
            }
            if (!empty($message["text_body"])) {
                $messageObj->setTextBody($message["text_body"]);
            }
            return $messageObj;
        }
        return false;
    }
}   

到此 我们就实现了redis队列异步发送邮件

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23137.html

相关文章

  • 使用 mixphp 打造多进程异步邮件发送

    摘要:消费者开发本例我们使用的多进程开发工具来完成这个需求,通常使用常驻进程来处理队列的消费,所以我们使用的类型,模式。中进程负责执行邮件发送任务。此时终端将打印成功收到测试邮件官网 注意:这个是 MixPHP V1 的范例 邮件发送是很常见的需求,由于发送邮件的操作一般是比较耗时的,所以我们一般采用异步处理来提升用户体验,而异步通常我们使用消息队列来实现。 传统 MVC 框架由于缺少多进程...

    EdwardUp 评论0 收藏0
  • Mix PHP V2 实例:协程池异步邮件发送守护程序

    摘要:消费者开发使用本例时,请确保你使用的编译时开启了本例我们采用的守护程序协程池来完成一个超高性能的邮件发送程序。 去年 Mix PHP V1 发布时,我写了一个多进程的邮件发送实例: 使用 mixphp 打造多进程异步邮件发送,今年 Mix PHP V2 发布,全面的协程支持让我们可以使用一个进程就可达到之前多个进程都无法达到的更高 IO 性能,所以今天重写一个协程池版本的邮件发送实例。...

    lauren_liuling 评论0 收藏0
  • SegmentFault 技术周刊 Vol.37 - 分布式缓存利器:Redis

    摘要:持久化到中反向代理的负载均衡基于的集群搭建如何实现从中订阅消息转发到客户端的扩展是阻塞式,使用订阅发布模式时,会导致整个进程进入阻塞。缓存是用于解决高并发场景下系统的性能及稳定性问题的银弹。 showImg(https://segmentfault.com/img/bVYE6k?w=900&h=385); Redis 是由意大利程序员 Salvatore Sanfilippo(昵称:a...

    binaryTree 评论0 收藏0
  • Mix PHP V2 实例:AliCloud 短信协程池异步发送守护程序

    摘要:前些时间我们发布了实例协程池异步邮件发送守护程序范例,这一次我们提供一个使用大厂通过协程化来并行执行短信发送任务,本文是一个代码简单性能极强的范例。 前些时间我们发布了 Mix PHP V2 实例:协程池异步邮件发送守护程序 范例,这一次我们提供一个使用大厂 SDK 通过 Swoole Hook 协程化来并行执行短信发送任务,本文是一个代码简单、IO 性能极强的范例。 请先升级到 m...

    qc1iu 评论0 收藏0

发表评论

0条评论

娣辩孩

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<