最近一直在赶项目,内心但是百感交集。一方面是因为学而知不足,另外一方面更是感叹互联网的发展突飞猛进。有时候你不进步就是等于在退步。小侠最近心血来潮想用好好地在项目中用下队列。尽管没什么高并发的存在。但是对于一些业务解耦队列仍是一个不错的解决方案。php
#消息队列html
“消息队列”是指消息的传输过程当中保存消息的容器。前端
“消息”是在两台计算机间传送的数据单位。消息能够很是简单,例如只包含文本字符串;也能够更复杂,可能包含嵌入对象。mysql
#应用场景laravel
如下介绍消息队列在实际应用中经常使用的使用场景。异步处理,应用解耦,流量削锋和消息通信四个场景。sql
异步处理 数据库
场景说明:用户注册后,须要发注册邮件和注册短信。传统的作法有两种:bash
1.串行的方式。服务器
2.并行方式。 网络
(1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务所有完成后,返回给客户端。
假设三个业务节点每一个使用50毫秒钟,不考虑网络等其余开销,则串行方式的时间是150毫秒,并行的时间多是100毫秒。 由于CPU在单位时间内处理的请求数是必定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。 小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢? 引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构以下
按照以上约定,用户的响应时间至关因而注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,所以写入消息队列的速度很快,基本能够忽略,所以用户的响应时间多是50毫秒。所以架构改变后,系统的吞吐量提升到每秒20 QPS。比串行提升了3倍,比并行提升了两倍。
场景说明:用户下单后,订单系统须要通知库存系统。传统的作法是,订单系统调用库存系统的接口。以下图:
传统模式的缺点:
1) 假如库存系统没法访问,则订单减库存将失败,从而致使订单失败;
2) 订单系统与库存系统耦合;
如何解决以上问题呢?引入应用消息队列后的方案,以下图:
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操做。
假如:在下单时库存系统不能正常使用。也不影响正常下单,由于下单后,订单系统写入消息队列就再也不关心其余的后续操做了。实现订单系统与库存系统的应用解耦
流量削锋也是消息队列中的经常使用场景,通常在秒杀或团抢活动中使用普遍。
应用场景:秒杀活动,通常会由于流量过大,致使流量暴增,应用挂掉。为解决这个问题,通常须要在应用前端加入消息队列。
消息通信是指,消息队列通常都内置了高效的通讯机制,所以也能够用在纯的消息通信。好比实现点对点消息队列,或者聊天室等。 点对点通信
点对点通信:
客户端A和客户端B使用同一队列,进行消息通信。
聊天室通信:
客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现相似聊天室效果。 以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图
以上就是就是对于队列的理解和应用。若是你想了解更多。你能够参考进入如下网址。了解更多关于队列的应用www.365jz.com/article/239…上面小侠的说明就是引用了这部分文章的。
----------------------------------------------------------------------------------------------------------
本次咱们基于演示的是邮件队列如何操做。
本次实现队列的方式咱们采用了mysql。若是你想了解更多或者配置其余方式的队列记得好好查看laravel的官方手册。
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复制代码