1.MQ实现了什么,解耦,异步,削峰
解耦:以接口模式给其他系统发送数据,配置麻烦,系统变动,相关配置就要改变,队列这是生产消费模式,只需要生产,其他系统要消费就自己拿
异步:用户>系统>队列>多个其他系统, 系统只要把请求给了队列,就可以返回给用户,没队列则每个系统都要去请求
削峰:大量并发请求,可以插入队列,让队列平滑请求,减少服务器压力
2.队列的优缺点
可用性降低:加了一层队列,那么多一层风险,
复杂度提高:一致性,不被重复消费,消息可靠传输
一致性:用户>系统>队列>多个其他系统。请求从队列到多个系统,假如其中一个写入失败,数据就不一致
3.如何保证RabbitMQ消息的顺序性?
将原来的一个queue拆分成多个queue,每个queue都有一个自己的consumer。该种方案的核心
是生产者在投递消息的时候根据业务数据关键值(例如订单ID哈希值对订单队列数取模)来将需要
保证先后顺序的同一类数据 发送到同一个queue当中。
4.消息怎么路由
消息提供方->路由->一至多个队列消息发布到交换器时,消息将拥有一个路由键(routing key),
在消息创建时设定。通过队列路由键,可以把队列绑定到交换器上。消息到达交换器后,
RabbitMQ 会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则);
常用的交换器主要分为一下三种:
1. fanout:如果交换器收到消息,将会广播到所有绑定的队列上
2. direct:如果路由键完全匹配,消息就被投递到相应的队列
3. topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic 交换器时,可以使用通
配符
5.如何保证消息不被重复消费 1..生产时消息重复,2.消费时消息重复。
1.生产消息重复: 生产》mq,mq确认的时候出现网络波动,生产没有收到确认,实际mq已经接收到了消息。
这时候生产就会重发一遍。生产如果消息未被确认,或确认失败,可以使用定时任务+redis/db,来进行消息重试
2.消费成功后,给mq确认出现网络波动,mq没有接收到确认。mq就会继续给消费投递之前的消息,这时候消息着就接收到了两条一样的消息
解决:
1.每个消息带1个全局唯一ID,
2.消费者get到消息后根据id去redis查是否存在 不存在则消费,并写入redis,存在则直接丢弃
6.如何确保消息接收方消费了消息
1.将信道设置成confirm模式,信道会发送1个消息唯一id,
发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到
达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息。
接收方确认也是异步的,只有消费者确认了mq才会把消息从队列删除
7.如何保证mq消息丢失
生产者丢失消息
confirm模式:一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一
的ID(从1开始),一旦消息被投递到所有匹配的队列之后;rabbitMQ就会发送一个ACK给生产者
(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;如果rabbitMQ没能
处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。
处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制
配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁
盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。
8.mq为什么不应该对所有message使用持久化?
1.必然导致性能下载,持久化是写磁盘的,和写内存相差10倍
所以,是否要对 message 进行持久化,需要综合考虑性能需要,以及可能遇到的问题。若想达到
100,000 条/秒以上的消息吞吐量(单 RabbitMQ 服务器),则要么使用其他的方式来确保
message 的可靠 delivery ,要么使用非常快速的存储系统以支持全持久化(例如使用 SSD)。另
外一种处理原则是:仅对关键消息作持久化处理(根据业务重要程度),且应该保证关键消息的量
不会导致性能瓶颈。
9.如何保证mq的高可用?
mq基于主从模式做高可用,有三种模式:单机,集群,镜像集群
单机一般就是demo,生产基本不会用
普通集群:多台机器多个mq实例(每个机器启动1个mq)。队列只会放在1个mq上,但是每个mq都会同步队列的元数据(队列的一些配置,通过元数据定位到队列所在的实例)。
消费的时候,连接到了另外的mq,那么这个mq就会从队列所在的mq上拉数据过来
提高吞吐量,集群中多个节点服务某个队列的读写操作。
镜像集群模式:
这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群
模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是
说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意
思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。
RabbitMQ 有很好的管理控制台,就是在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次
创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。
这样的好处在于,你任何一个机器宕机了,没事儿,其它机器(节点)还包含了这个 queue
的完整数据,别的 consumer 都可以到其它节点上去消费数据。坏处在于,第一,这个性能
开销也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!RabbitMQ 一
个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整
数据。
10.mq队列满了,消息积压怎么处理?
例:每次消费都写mysql,mysql挂了,消费就不动了,或者消费慢,生产极快
1.修复consumer慢的问题,停掉现有的consumer
2.新建topic放10倍的quenue和10倍的消费者去消费原先的挤压数据,之后回归正常的架构
11.mq设置过期时间,消息过期了怎么办?
1.增加数据库中间表,让它丢失,然后再晚上的时候从中间表找出来重新写进去
12.死信队列
消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false。
消息TTL过期。
队列满了,无法再添加。
1.死信队列的数据,看业务处理
3.rabbitMQ的角色
Broker: 简单来说就是消息队列服务器实体
Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
VHost: vhost 可以理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的
queue、exchange 和 binding 等,但最最重要的是,其拥有独立的权限系统,可以做到 vhost 范
围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段(一个典型
的例子就是不同的应用可以跑在不同的 vhost 中)。
Producer: 消息生产者,就是投递消息的程序
Consumer: 消息消费者,就是接受消息的程序
Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话
任务
4.RabbitMQ 5种工作模式
1.simple(最简单的收发模式) 消费监听消费队列,有消息就被队列拿走
缺点:消费没被正确取来,消息就消费了造成消息丢失。这里可以设置成 手动的ack,但如果设置成手动ack,处理完后要及时发送ack消息给队列,否则会造成内存溢出
2.work工作模式(资源的竞争)C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息
缺点:高并发情况下,默认会产生某 一个消息被多个消费者共同使用,可以设置一个开关(syncronize)保证f消息只能被一个消费者使 用)。
3.publish/subscribe发布订阅(共享资源)每个消费者监听自己的队列
生产者将消息发给队列,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队
列都将接收到消息。
4.routing路由模式 只能匹配上路由key对应的消息队列,对应的消费者才能消费消息
![](https://img2022.cnblogs.com/blog/979045/202202/979045-20220228113809647-1065322482.png)
消息生产者将消息发送给交换机按照路由判断,路由是字符串(info) 当前产生的消息携带路由字符(对
象的方法),交换机根据路由的key,只能匹配上路由key对应的消息队列,对应的消费者才能消费消息;
根据业务功能定义路由字符串
从系统的代码逻辑中获取对应的功能字符串,将消息任务扔到对应的队列中。
业务场景:error 通知;EXCEPTION;错误通知的功能;传统意义的错误通知;客户通知;利用key路由,可
以将程序中的错误封装成消息传入到消息队列中,开发者可以自定义消费者,实时接收错误;
5.topic 主题模式(路由模式的一种) 增加匹配功能
![](https://img2022.cnblogs.com/blog/979045/202202/979045-20220228114015805-1222797182.png)
* , # 代表通配符* 代表多个单词, # 代表一个单词
路由功能添加模糊匹配
消息产生者产生消息,把消息交给交换机
交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消费
mq选择
1.中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;
2.大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
3.大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃
度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
|
Active MQ
|
RabbitMQ
|
RocketMQ
|
Kafka
|
单机 吞吐 星
|
万级,比
RocketMQ、
Kafka低一个
数量级
|
同
ActiveMQ
|
10万级,支撞高吞吐
|
10万级,高吞吐,一般配合大数据类的 系统来进行实时数据计算、日志采集等场 景
|
topic
数星 对吞 吐的影 响
|
|
|
topic可以达到几百/几千的级 另U,吞吐量会有较小幅度的下 降,这是RocketMQ的一大优 势,在同等机器下.可以支撑大 是的topic
|
topic从几十到几百个时候,吞吐星会大 幅度下降,在同等机器下,Kafka尽量保 证topic数量不要过多,如果要支撑大规 模的topic ,需要増加更多的机器资源
|
时效 性
|
ms级
|
钢级忑 是
RabbitMQ 的一大特 点,延迟最 低
|
ms级
|
延退在ms级以内
|
可用 性
|
高,基于主 从给实现 高B用
|
同
ActiveMQ
|
非常高,分布式架构
|
非常高,分布式,一个数据多个副本,少 数机器宕机r不会丢失数据,不会导致不 可用
|
消息 可靠 性
|
有较低的概 率丢失数据
|
球不丢
|
经过参数优化配置,可以做到0 丢失
|
同 RocketMQ
|
功能 支持
|
MQ领域的 功能极其完 备
|
基于erlang 开发,并发 能力很强, 性
延时很低
|
MQ功能较为完善,还是分布式 的,扩展性好
|
功能较为简单,主要支持简单的MQ功 能,在大数据领域的实时计算以及日志采 集?Ml模使用
|