1.使用mq的优点

  1. mq可以解耦合,耦合度比较低(解耦合)

  2. 吞吐量提升:无需等待订阅者处理完成,响应更快速(交给mq之后就行了,不管后续的操作)

  3. 故障隔离:服务没有直接调用,不存在级联失败问题(mq把服务都间隔开了,故障也相隔开了)

  4. 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件(可以起到流量缓冲的作用)

2.常见的四种队列:

image.png

1. 四种MQ对比:

  1. kafka 跟RockertMQ在大数据领域使用的特别多(单机吞吐量高 特别是kafka )
  2. kafka的性能最高,处理的并发量,RoketMq其次。
  3. 可用性最高的是RabbitMQ
  4. 消息延迟RabbitMQ (微秒级)kafka(毫秒以内) RoketMQ(毫秒级)
  5. 消息的可靠性:RabbitMq(高)
  6. 金融类(RabbitMq) 大数据,数据量比较大(kafka,RoketMq)

3.RabbitMq的结构和概念

image.png
image.png

4. Spring整合的RabbitMq的 AMQP(接受和消费图解)

发送消息
image.png
监听消息
image.png

5. 5种队列模式

image.png
路由:

主题:
image.png

image.png

6.MQ如何保证消息的可靠性

1.生产者的确认机制:

在发送消息的时候给消息指定一个唯一标识id。消息发送到Mq以后,会返回一个结果给发送者,表示消息是否处理成功,返回ack确认字符
image.png
发送:(uuid作为全局id)
image.png
接受:
image.png
俩种都要确认(消息到交换机,消息到队列中)
image.png

2.mq的持久化

生产者确认可以确保消息投递到RabbitMQ的队列中,但是消息发送到RabbitMQ以后,如果突然宕机,也可能导致消息丢失。
队列,交换机,以及消息都要进行持久化(交换机一般不进行持久化,很少出问题)
要想确保消息在RabbitMQ中安全保存,必须开启消息持久化机制。
Mq就是持久化的,持久化到硬盘中的,不设置的默认就是持久化的

3. 消费者确认机制

消费者返回ack才会删除队列里面的消息;
image.png
image.png
acknowledge-mode : 三种机制
//项目中使用地是Auto模式,manual太麻烦了// 俩者都不会造成消息丢失
但是会无限重试;消费者一直消费,mq压力特别大
manual:
image.png

4.消费者重试机制

原因:当消费者出现异常后,消息会不断requeue(重入队)到队列,再重新发送给消费者,然后再次异常,再次requeue,无限循环,导致mq的消息处理飙升,带来不必要的压力:
image.png
image.png
但是这样消息还是会被丢失!!
还有一个限制最大时间的参数:
image.png
允许等待的最大时间,默认是50秒
最后一个参数:有事务为false,没有事务返回true

4.2 失败策略:
image.png
默认是直接丢失:

消息转换器,消息失败后 将消息投递到异常交换机中,交给人工处理
image.png
或者堆积在死信交换机里
图解:
image.png

7.死信交换机:

image.png

1. 什么是死信交换机:

  • 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false(重入队列被设置为false)
  • 消息是一个过期消息,超时无人消费
  • 要投递的队列消息满了,无法投递

image.png
也可以在重试次数过后放入死信交换机
image.png

2. 消息超时时间的俩种方式,例子:

MQ初级高级到结合Stream - 图25

8. 延时队列

1. 使用场景:

  • 延迟发送短信
  • 用户下单,如果用户在15 分钟内未支付,则自动取消
  • 预约工作会议,20分钟后自动通知所有参会人员

生产者:
image.png
消费者:
image.png

2. 使用步骤:

image.png

9 . 消息堆积问题

当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。
image.png
image.png

  • 消费者使用线程池
  • 增加更多消费者,提高消费速度。也就是我们之前说的work queue模式
  • 扩大队列容积,提高堆积上限

    1. 惰性队列

    从RabbitMQ的3.6.0版本开始,就增加了Lazy Queues的概念,也就是惰性队列。惰性队列的特征如下:

  • 接收到消息后直接存入磁盘而非内存

  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储

11. Mq的集群

1. 普通集群(不具备高可用)

普通集群,或者叫标准集群(classic cluster),具备下列特征:

  • 会在集群的各个节点间共享部分数据,包括:交换机、队列元信息。不包含队列中的消息。
  • 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回
  • 队列所在节点宕机,队列中的消息就会丢失

(当消息发送过来时,会由集群路由到相对应的队列中。即使当前服务没有该队列)
image.png

2. 镜像集群

镜像集群:本质是主从模式,具备下面的特征:

  • 交换机、队列、队列中的消息会在各个mq的镜像节点之间同步备份。
  • 创建队列的节点被称为该队列的主节点,备份到的其它节点叫做该队列的镜像节点。
  • 一个队列的主节点可能是另一个队列的镜像节点
  • 所有操作都是主节点完成,然后同步给镜像节点
  • 主宕机后,镜像节点会替代成新的主

image.png
(镜像集群可能会存在消息丢失,就是主节点如果宕机后还没来得及备份就挂机了,存在延时没备份的情况)

3. 仲裁队列

仲裁队列:仲裁队列是3.8版本以后才有的新功能,用来替代镜像队列,具备下列特征:

  • 与镜像队列一样,都是主从模式,支持主从数据同步
  • 使用非常简单,没有复杂的配置
  • 主从同步基于Raft协议,强一致

image.png

image.png
image.png

4. 集群的扩容

使用同一个cookie
image.png

5. SpringAMQP连接集群

image.png