RabbitMQ简介

介绍

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP(高级消息队列协议)来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。生产者将消息发送给Exchange(交换器),Exchange根据路由规则,将消息转发给指定的消息队列。消息队列储存消息,等待消费者取出消息,消费者通过建立与消息队列相连的信道,从消息队列中获取消息。

应用场景

1. 解耦
比如,实现订单系统和库存系统解耦,订单系统只负责将下单消息放入队列,后续的操作它都不用关心;库存系统订阅下单的消息,然后修改库存。所以即使库存系统出现问题,用户还是可以正常下单。

2. 并行提升效率
比如,用户注册后,需要发注册邮件和注册短信,如果采用串行,先发送注册邮件,再发送注册短信,两个任务全部完成后才返回给客户端;如果采用并行,发送邮件的同时发送短信,可以缩短用户的等待时间。

3. 流量削峰
流量削峰也是消息队列中的常用场景,一般在秒杀活动中使用广泛。将所有请求写入消息队列,系统从MQ中慢慢拉取请求,所以在秒杀期间(将近一小时)可能会有几十万或者几百万的请求积压在MQ中,这个短暂的高峰期积压是没问题的,只要高峰期一过,系统就会快速将积压的消息消费掉。

交换机类型

RabbitMQ常用的交换器类型有direct、topic、fanout、headers四种:

Direct Exchange(直连):此交换机只绑定一个队列,接收到的消息只转发到该队列上,点对点发送。
Fanout Exchange(扇形):发送到该交换机的所有消息都会被转发到与该交换机绑定的所有队列上。
Topic Exchange(主题):通过匹配消息的RoutingKey与路由器和队列之间的绑定来将消息转发到匹配的队列上,通配符有两种:"*" (匹配一个词)、"#"(匹配多个词)。
Headers Exchange(头):创建队列时设置头部信息(键值对),发送消息的时候在请求头中加上要匹配的键值对信息,有完全匹配(all)和部分匹配(any)两种模式。

六种工作模式

1. 基本消息模型
一个生产者,一个队列,一个消费者。
2. Work queues
一个生产者,一个队列,多个消费者,但是一个消息只能被一个消费者获取。
3. Publish/Subscribe
一个生产者,一个交换机(类型为Fanout),多个队列,多个消费者,每个队列得到的消息是一样的。
4. Routing路由模型
在发布/订阅模式基础之上,交换机类型为Direct,相匹配的队列才会收到消息。
5. Topics主题模式
在发布/订阅模式基础之上,交换机类型为Topic,在匹配上比Routing路由模型更灵活。
6. RPC(远程过程调用)
消息队列是基于异步的,生产者把消息发送到队列后,并不知道消费者处理成功或者失败,在现实中,很多时候需要确认消费者处理成功后再进行下一步操作,这就相当于RPC。

RabbitMQ实现RPC的流程是(参考:https://blog.csdn.net/weixin_43498985/article/details/119026198):

  1. 生产者发送消息时,在消息的属性(AMQP协议中定义了14个属性,这些属性会随着消息一起发送)中设置两个属性值replyTo(Queue的名称,用于告诉消费者处理完成后将通知我的消息发送到这个Queue中)和correlationId(此次请求的标识号,消费者处理完成后需要将此属性返还,生产者将根据这个id了解哪条请求被成功执行了或执行失败)。
  2. 消费者处理完消息后,将生成一条应答消息到replyTo指定的Queue,同时带上correlationId属性。
  3. 生产者之前已订阅replyTo指定的Queue,从中收到服务器的应答消息后,根据其中的correlationId属性分析哪条请求被执行了,根据执行结果进行后续业务处理。

消息机制

1. 消息确认机制
为了保证消息可靠,RabbitMQ提供了消息确认机制,消费者订阅队列的时候,可以指定autoAck参数,autoAck为true表示自动确认模式,即RabbitMQ自动将发出的消息设置为确认,然后删除消息而不管是否真的被消费;autoAck为false表示等待消费者返回确认,收到确认后再将消息删除,如果没收到确认并且消费者与RabbitMQ之间的连接断开,则将消息发送给其他消费者(存在多个消费者)。

2. 消息持久化机制
RabbitMQ的持久化分为三个部分:交换机持久化、队列持久化和消息的持久化。交换机如果不持久化,重启之后其元数据会丢失(交换机的配置信息),队列持久化能保证自身的元数据不会因为异常而丢失,但是不能保证内部的消息不会丢失,所以必须设置消息持久化,如果只设置队列持久化或者消息持久化,重启之后消息都会消失。

3. 消息分发机制
轮询分发:队列所有的消费者得到的数量是一样的,并不会因为两个消费者处理数据速度不一样使得两个消费者取得不一样数量的数据,这可能出现消息丢失的情况。公平分发:消费者设置每次从队列里取一条数据,并且关闭自动回复机制,在每次处理完数据后手动给队列发送确认,然后取下一条数据,采用公平分发方式就不会出现消息丢失。

4. 生存时间
RabbitMQ支持设置消息的过期时间,在消息发送的时候可以进行指定;RabbitMQ支持设置队列的过期时间,从消息入队列开始计算,直到超过了队列的超时时间配置,那么消息会变成死信,自动清除。如果两种方式一起使用,以小为准;如果设置为0,则表示除非此时可以直接将消息投递到消费者,否则该消息将被立即丢弃。

5. 死信队列
当消息在一个队列中变成死信之后,它能被重新发送到一个交换器中,这个交换器称为死信交换器,与该交换器绑定的队列称为死信队列。死信队列可用于分析异常,进而改善系统。

6. 延迟队列
延迟队列中存储的对象是的延迟消息,进入该队列的消息会被消费者延迟消费,延迟队列的典型应用场景有延迟重试、30分钟内支付。

特性

消息路由(支持):RabbitMQ可以通过不同的交换器支持不同种类的消息路由;
消息有序(不支持):当消费消息时,如果消费失败,消息会被放回队列,然后重新消费,这样会导致消息无序;
消息时序(非常好):通过延时队列,可以指定消息的延时时间,过期时间TTL等;
容错处理(非常好):通过交付重试和死信交换器(DLX)来处理消息处理故障;
伸缩(一般):master queue只有一个,负载只有这一个master queue去抗;
持久化(不好):没有消费的消息,可以支持持久化,这个是为了保证机器宕机时消息可以恢复,但是消费过的消息,就会被马上删除,因为RabbitMQ就不是为了存储历史数据的;
消息回溯(不支持):因为消息不支持永久保存,所以自然就不支持回溯;
高吞吐(中等):因为所有的请求都是在master queue上执行,导致单机性能达不到十万级的标准。

参考:
https://blog.csdn.net/weixin_39327556/article/details/124768245
https://blog.csdn.net/weixin_43498985/article/details/119026198
https://blog.csdn.net/kavito/article/details/91403659

posted @   学海无涯#  阅读(151)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示