laravel中使用利用消息队列发送邮件

前言.

最近一直在赶项目,内心但是百感交集。一方面是因为学而知不足,另外一方面更是感叹互联网的发展突飞猛进。有时候你不进步就是等于在退步。小侠最近心血来潮想用好好地在项目中用下队列。尽管没什么高并发的存在。但是对于一些业务解耦队列仍是一个不错的解决方案。php


什么是消息队列?消息队列能够用在什么地方?

#消息队列html

“消息队列”是指消息的传输过程当中保存消息的容器。前端

“消息”是在两台计算机间传送的数据单位。消息能够很是简单,例如只包含文本字符串;也能够更复杂,可能包含嵌入对象。mysql

消息被发送到队列中。“消息队列”是在消息的传输过程当中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;若是发送消息时接收者不可用,消息队列会保留消息,直到能够成功地传递它。

#应用场景laravel

如下介绍消息队列在实际应用中经常使用的使用场景。异步处理,应用解耦,流量削锋和消息通信四个场景。sql

异步处理 数据库

场景说明:用户注册后,须要发注册邮件和注册短信。传统的作法有两种:bash

1.串行的方式。服务器

2.并行方式。 网络

(1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务所有完成后,返回给客户端。


(2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差异是,并行的方式能够提升处理的时间。


假设三个业务节点每一个使用50毫秒钟,不考虑网络等其余开销,则串行方式的时间是150毫秒,并行的时间多是100毫秒。 由于CPU在单位时间内处理的请求数是必定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。 小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢? 引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构以下 


按照以上约定,用户的响应时间至关因而注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,所以写入消息队列的速度很快,基本能够忽略,所以用户的响应时间多是50毫秒。所以架构改变后,系统的吞吐量提升到每秒20 QPS。比串行提升了3倍,比并行提升了两倍。 


应用解耦

场景说明:用户下单后,订单系统须要通知库存系统。传统的作法是,订单系统调用库存系统的接口。以下图:

传统模式的缺点: 

 1) 假如库存系统没法访问,则订单减库存将失败,从而致使订单失败;

 2) 订单系统与库存系统耦合; 

如何解决以上问题呢?引入应用消息队列后的方案,以下图: 


订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。 

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操做。

 假如:在下单时库存系统不能正常使用。也不影响正常下单,由于下单后,订单系统写入消息队列就再也不关心其余的后续操做了。实现订单系统与库存系统的应用解耦 


流量削锋

流量削锋也是消息队列中的经常使用场景,通常在秒杀或团抢活动中使用普遍。

 应用场景:秒杀活动,通常会由于流量过大,致使流量暴增,应用挂掉。为解决这个问题,通常须要在应用前端加入消息队列

  1. 能够控制活动的人数;
  2. 能够缓解短期内高流量压垮应用


  • 用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面;
  • 秒杀业务根据消息队列中的请求信息,再作后续处理。

  • 消息通信

    消息通信是指,消息队列通常都内置了高效的通讯机制,所以也能够用在纯的消息通信。好比实现点对点消息队列,或者聊天室等。 点对点通信

    点对点通信:


    客户端A和客户端B使用同一队列,进行消息通信。

    聊天室通信:


    客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现相似聊天室效果。 以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图


    以上就是就是对于队列的理解和应用。若是你想了解更多。你能够参考进入如下网址。了解更多关于队列的应用www.365jz.com/article/239…上面小侠的说明就是引用了这部分文章的。

    ----------------------------------------------------------------------------------------------------------

    实战部分

    本次咱们基于演示的是邮件队列如何操做。

    本次实现队列的方式咱们采用了mysql。若是你想了解更多或者配置其余方式的队列记得好好查看laravel的官方手册。

    第一步:修改.evn文件中的队列方式。

    QUEUE_DRIVER=database复制代码

    第二步:要使用 database 队列驱动,你须要数据表保存任务信息。要生成建立这些表的迁移,能够运行 Artisan 命令 queue:table,迁移被建立以后,可使用 migrate 命令生成这些表:

    php artisan queue:table
    php artisan migrate复制代码

    第三步:为对应的队列生成一个队列的操做类

    php artisan make:job SendPostEmail
    #以上命令咱们就能够在laravel里生成一个任务操做类,其代码位置在:app/Jobs复制代码

    第四步:咱们须要构建一个测试发送邮件的方法

    <?php
    
    namespace App\Http\Controllers\Queue;
    
    use App\Post;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Mail;
    //引入须要使用的队列
    use App\Jobs\SendPostEmail;
    class IndexController extends Controller
    {
        public function sendemail(){
                //Post表是本次发送内容的信息表
                $post = new Post();
                $post->title = "队列测试邮件";
                $post->body = "这是测试邮件";
                $post->save();
                //此操做是说明信息内容写入成功后,咱们把写入的内容进行入队列的操做
                $this->dispatch(new SendPostEmail($post)); // 队列
        }
    }
    复制代码

    第五步:编写的队列操做类

    <?php
    
    namespace App\Jobs;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Mail;
    use App\Post;
    class SendPostEmail implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        protected $post;
        /**
         * Create a new job instance.
         *
         * @return void
         */
        public function __construct(Post $post)
        {
            $this->post = $post;
        }
    
        /**
         * Execute the job.
         *
         * @return void
         */
        public function handle()
        {
            //
            $data= array(
                'title'=> $this->post->title,
                'body'=> $this->post->body,
            );
            Mail::send('test', $data, function($message){
                $to = 'fivetong@163.com';
                $message->to($to)->subject('测试邮件');
            });
    
        }
    }
    
    #从上面能够看到,构造函数中咱们直接存入了对应的POST实例复制代码

    第六步:经过命令执行开启队列应用

    php artisan queue:work
    #注意了,队列启动后若是有任何的数据修改记得重启队列。
    php artisan queue:restart复制代码

    第七步:访问对应的测试邮件连接检查邮件是否能够发送成功


    以上就是一个简单的邮件队列的构建过程。固然小侠在作这个的时候也是踩了不少的坑。其实里面还有不少错误记录,日志和失败的处理方法没有介绍。不过正因如此才能激起你们的学习和求知欲望。若是你对队列有他更多的求知欲那么就好好看看laravel手册吧。这里小侠为你们放上连接:laravelacademy.org/post/8369.h…

    相关文章
    相关标签/搜索