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

前言.

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


什么是消息队列?消息队列可以用在什么地方?

#消息队列

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

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

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

#应用场景

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

异步处理 

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

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…



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值