深入了解消息队列


消息队列是一种 “先进先出” 的数据结构

一、为什么要用消息队列

常见应用场景:解耦、异步、削峰

1、解耦

高内聚、低耦合,耦合性越高,容错性越低。

应用场景:用户创建订单后,调用支付系统、库存系统、物流系统,如果其中一个出现故障暂时无法使用,都会造成下单操作异常,影响用户体验
在这里插入图片描述


使用消息队列解耦,系统的耦合性就会提高了。
比如物流系统发生故障,需要几分钟才能来修复,在这段时间内,物流系统要处理的数据被缓存到消息队列中,用户的下单操作正常完成。当物流系统恢复后,补充处理存在消息队列中的订单消息即可,终端系统感知不到物流系统发生过几分钟故障。
在这里插入图片描述

2、异步

A系统接收一个请求,A系统本身还需要在B、C、D三个系统,自己需要 3ms,B、C、D三个系统分别需要300ms、450ms、200ms。最终请求总延时是3+300+450+200=953ms,接近1s,用户非常不好。
在这里插入图片描述


如果使用MQ,那么A系统连续发送3条消息到MQ队列中,假如耗时5ms,A系统从接受一个请求到返回响应给用户,总时长是3+5=8ms,对于用户而言,响应速度大大提升了,改善了用户的体验。
在这里插入图片描述

3、削峰

应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提到系统的稳定性和用户体验。
在这里插入图片描述


如果系统负载超过阈值,就会阻止用户请求,如果使用消息队列将用户请求缓存起来,可以缓解短时间内高流量压垮应用。
在这里插入图片描述

二、消息队列产品的比较

在这里插入图片描述
在这里插入图片描述

三、消息队列的优点和缺点

优点:解耦、异步、削峰
缺点:系统可用性降低、系统复杂度提高、数据一致性问题

1、如何保证消息队列的高可用

rabbitMQ高可用–镜像集群

1.在多台机器上分别启动RabbitMQ实例。
2.多个实例之间可以相互通信。
3.每次生产者写消息到queue的时候,都会自动把消息同步到多个实例的queue上。每个RabbitMQ节点上都有Queue的消息数据和元数据。
4.某一个节点宕机,其他节点依然保存完整数据,不影响客户端消费。

在这里插入图片描述

1.2、如何保证消息不丢失

消息丢失原因

情况一:生产者没有成功发送到MQ
情况二:消息发送给MQ后,MQ宕机导致内存中的消息数据丢失
情况三:消费者获取到消息,但消费者还没有来得及处理宕机了,但此时 MQ中消息已经删除,消费者重启后不能再消费之前的消息
在这里插入图片描述


确保消息不丢失方案

1、生产者发送给MQ后,MQ给生产者确认(confirm)收到,MQ收到消息后进行消息持久化
3、消费者收到消息处理完毕后手动进行ack确认
4、MQ收到消费者确认(ack)后删除持久化的消息

在这里插入图片描述

1.3、如何保证消息不被重复消费

1、生产者发送消息时携带一个全局唯一的消息id
2、消费者获取消费后先根据id在redis/db中查询是否存在消费记录
3、如果没有消费过就正常消费,消费完毕后写入redis/db
4、如果消息消费过就直接舍弃

1.4、如何保证消息消费的顺序性

1、生产者将同一组消息发送到单个队列
2、多个消费者并行对消息进行消费
3、Queue通过分段锁保证消息消费的顺序性

在这里插入图片描述

四、实例

<?php
namespace app\index\controller;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use think\Controller;
use think\Db;

class Index extends Controller
{
   
    protected static $queue = 'user_queue';
    protected static $exchange = 'user_exchange'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值