RabbitMQ知识概括详解(2022)

目录

什么是RabbitMQ🍉

MQ的优点🌹

解耦、异步、削峰❀

消息队列有什么缺点🦖

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

 RabbitMQ的工作模式🍅

一.simple模式(即最简单的收发模式)

二.work工作模式(资源的竞争)

三.publish/subscribe发布订阅(共享资源)

四.routing路由模式

五.topic 主题模式(路由模式的一种) 

如何保证RabbitMQ消息的顺序性?😚

如何保证RabbitMQ消息的可靠传输? 


什么是RabbitMQ🍉

RabbitMQ 是一款开源的, Erlang 编写的,消息中间件; 最大的特点就是消费并不需要确保提供方
存在 , 实现了服务之间的高度解耦 可以用它来:解耦、异步、削峰。

MQ的优点🌹

  • 异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。
  • 应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。
  • 流量削锋 - 可以通过消息队列长度控制请求量;可以缓解短时间内的高并发请求。
  • 日志处理 - 解决大量日志传输。
  • 消息通讯 - 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实 现点对点消息队列,或者聊天室等。

解耦、异步、削峰❀

  • 解耦A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如 C 系统现在不需要了呢?A 系统负责人几乎崩溃…A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。如果使用 MQA系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

            就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦。

  •  异步A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3msBCD 三个系统分别写库要 300ms450ms200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5msA系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms
  • 削峰 :减少高峰时期对服务器压力。

消息队列有什么缺点🦖

        缺点有以下几个:

               1. 系统可用性降低 本来系统运行好好的,现在你非要加入个消息队列进去,那消息队列挂了,你的系统不是呵 呵了。因此,系统可用性会降低;

                2. 系统复杂度提高 加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。
                3. 一致性问题 A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的。

KafkaActiveMQRabbitMQRocketMQ 有什么优缺点?

 

 RabbitMQ的工作模式🍅

.simple模式(即最简单的收发模式)

1. 消息产生消息,将消息放入队列
2. 消息的消费者 (consumer) 监听 消息队列 , 如果队列中有消息 , 就消费掉 , 消息被拿走后 , 自动从队列中 删除( 隐患 消息可能没有被消费者正确处理 , 已经从队列中消失了 , 造成消息的丢失,这里可以设置 成手动的ack, 但如果设置成手动 ack ,处理完后要及时发送 ack 消息给队列,否则会造成内存溢
)

.work工作模式(资源的竞争)

 

1. 消息产生者将消息放入队列消费者可以有多个 , 消费者 1, 消费者 2 同时监听同一个队列 , 消息被消费。 C1 C2共同争抢当前的消息队列内容 , 谁先拿到谁负责消费消息 ( 隐患:高并发情况下 , 默认会产生某 一个消息被多个消费者共同使用, 可以设置一个开关 (syncronize) 保证一条消息只能被一个消费者使用)

.publish/subscribe发布订阅(共享资源)

 

1. 每个消费者监听自己的队列;
2. 生产者将消息发给 broker ,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的
队列都将接收到消息。

.routing路由模式

 

 

1. 消息生产者将消息发送给交换机按照路由判断 , 路由是字符串 (info) 当前产生的消息携带路由字符
( 对象的方法 ), 交换机根据路由的 key, 只能匹配上路由 key 对应的消息队列 , 对应的消费者才能消费消 ;
2. 根据业务功能定义路由字符串
3. 从系统的代码逻辑中获取对应的功能字符串 , 将消息任务扔到对应的队列中。
4. 业务场景 :error 通知 ;EXCEPTION; 错误通知的功能 ; 传统意义的错误通知 ; 客户通知 ; 利用 key 路由 , 可 以将程序中的错误封装成消息传入到消息队列中, 开发者可以自定义消费者 , 实时接收错误 ;

.topic 主题模式(路由模式的一种) 

1. 星号井号代表通配符
2. 星号代表多个单词 , 井号代表一个单词
3. 路由功能添加模糊匹配
4. 消息产生者产生消息 , 把消息交给交换机
5. 交换机根据 key 的规则模糊匹配到对应的队列 , 由队列的监听消费者接收消息消费
(在我的理解看来就是 routing 查询的一种模糊匹配,就类似 sql 的模糊查询方式)

如何保证RabbitMQ消息的顺序性?😚

  1. 拆分多个 queue(消息队列),每个 queue(消息队列) 一个 consumer(消费者),就是多一些 queue (消息队列)而已,确实是麻烦点;
  2. 或者就一个 queue (消息队列)但是对应一个 consumer(消费者),然后这个 consumer(消费者)部用内存队列做排队,然后分发给底层不同的 worker 来处理。

如何保证RabbitMQ消息的可靠传输? 

  • 消息不可靠的情况可能是消息丢失,劫持等原因;
  • 丢失又分为:生产者丢失消息、消息列表丢失消息、消费者丢失消息;
1. 生产者丢失消息 :从生产者弄丢数据这个角度来看, RabbitMQ 提供 transaction confifirm 模式来 确保生产者不丢消息;
transaction 机制就是说:发送消息前,开启事务( channel.txSelect() , 然后发送消息,如果发送 过程中出现什么异常,事务就会回滚(channel.txRollback() , 如果发送成功则提交事务
channel.txCommit() )。然而,这种方式有个缺点:吞吐量下降;
confifirm 模式用的居多:一旦 channel 进入 confifirm 模式,所有在该信道上发布的消息都将会被指派 一个唯一的ID (从 1 开始),一旦消息被投递到所有匹配的队列之后;
rabbitMQ 就会发送一个 ACK 给生产者(包含消息的唯一 ID ),这就使得生产者知道消息已经正确 到达目的队列了;
如果 rabbitMQ 没能处理该消息,则会发送一个 Nack 消息给你,你可以进行重试操作。
2. 消息队列丢数据 :消息持久化。
处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。
这个持久化配置可以和 confifirm 机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个
Ack 信号。 这样,如果消息持久化磁盘之前,rabbitMQ 阵亡了,那么生产者收不到 Ack 信号,生产者会自动 重发。
那么如何持久化呢?
这里顺便说一下吧,其实也很容易,就下面两步
1. queue 的持久化标识 durable 设置为 true, 则代表是一个持久的队列
2. 发送消息的时候将 deliveryMode=2 这样设置以后,即使 rabbitMQ 挂了,重启后也能恢复数据
3. 消费者丢失消息 :消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息即可!
消费者在收到消息之后,处理消息之前,会自动回复 RabbitMQ 已收到消息;
如果这时处理消息失败,就会丢失该消息;
解决方案:处理消息成功后,手动回复确认消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我老伯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值