RabbitMQ
RabbitMQ由Erlang语言开发的基于AMQP协议的开源实现;RabbitMQ最初起源于金融系统,其主要关注的是系统的可用性以及 可靠性
RabbitMQ的特点
- 消息可靠性:通过发布确认,传输确认,持久化等措施保证消息的可靠性
- 路由灵活:通过Exchange对message进行路由
- 支持集群:支持多台MQ服务器组成一个集群,形成一个逻辑的Broker
- 高可用:队列在集群中存在镜像
- 支持多种协议:通过插件形式支持其余的协议(如:MQTT,STOMP)
- 提供可视化界面:提供监控界面
- 跟踪机制:提供消息的跟踪机制
- 拓展性强:通过插件支持更多的拓展
- RabbitMQ整体架构图:
RabbitMQ的消息持久化
- RabbitMQ的消息持久化包含两种策略,DISK以及RAM;
- DISK就是磁盘持久化,在持久化文件*.rdq过大时,会触发文件分裂;当*.rdp文件过小时会触发文件合并;
- RAM不会保存具体的message,需要从其它的节点同步;因此在集群中必然会存在一个DISK节点
- RabbitMQ的持久化涉及到三个方面的持久化,队列持久化,消息持久化,交换机持久化
- 通过将durable关键字设置为true,维持持久化
- 消息的持久化主要从消息安全性考虑,但是内存写入跟磁盘写入的速度存在很大的差异,将很大的影响吞吐量;
- RabbitMQ是否需要持久化取决于业务需求是重性能还是重消息的安全性
- 即便所有的持久化都设置为true,也未必可以保证消息不会丢失;因为无法保证消息的处理过程不会出现异常
- 消息的可靠性不仅于持久化有关,还与消息的确认模式有关
RabbitMQ的消息发布应答
- 为什么需要消息发布应答?
- 当生产者发布消息到Broker时,Broker不会做出任何响应;这就导致生产者无法知道消息是否发布成功.
- RabbitMQ对于生产者的消息应答具有两种解决策略
- 基于AMQP的事务机制(生产者需要同步等待Broker的执行结果,极大的影响性能)
- 信道支持确认模式(每一个message带有一个唯一ID,当message被投入Queue,信道会向生产者发送确认消息)
- AMQP一般采用发送方确认模式(异步),而不采用基于AMQP的事务机制(同步).
RabbitMQ的消息消费应答
- 为什么需要消息消费应答?
- Broker无法知道Consumer对于message是否消费成功.
- RabbitMQ通过消费者回执来确定Consumer是否消费成功
- RabbitMQ存在两种类别消费回执(手动回执,自动回执)
- 自动回执:当Broker把message发送给Consumer之后,不需要等待Consumer的确认回执,直接从队列中删除
- 手动回执:当Broker把message发送给Consumer之后,会收到Consumer的确认回执(ACK)后,才从队列中删除消息
- 消息拒绝策略:
- 当Consumer处理message失败时或者Consumer无法处理message时,可以要求Broker舍弃该message或者Broker重新将message投入队列
- 消息预取:
- 为什么需要消息预取?
- 实际的情况下,Consumer对于message处理的时间不一样;为了防止消费者无休止的取消息而无法消费导致OOM,进而导致系统崩溃;
- 什么是消息预取?
- 指Broker收到Consumer的下一个ACK之前,最多能够接受的message数目.( 防止消费者取消息于消费消息速度不一致,导致消息积压,而后发生系统崩溃)
RabbitMQ的流控机制
- RabbitMQ可以对内存,磁盘使用的上限设定阈值,当到达阈值时,生产者会阻塞,直至系统资源使用恢复正常;除了这两个操作,还可以通过流控机制保证系统的稳定性
- RabbitMQ通过Erlang实现,而Erlang中各进程不共享内存,默认Erlang不会对消息的内存上限设定阈值,所以极容易产生OOM,进而导致系统崩溃
- RabbitMQ通过基于Credit的流控机制,通过Credit的加加减减来来确定是否可以向消费者推送消息;当生产者的Credit大于0时,可以继续向消费者发送消息
- RabbitMQ通过监控每个进程的mailbox(消息容器),当无法即时处理消息时,mailbox会进行阻塞,当mailbox的容量到达上限时,会阻塞上游的消息推送;直至最上游的进程被阻塞.
- RabbitMQ具体流控机制如下:
当RabbitMQ的磁盘或者内存使用到达阈值时,会触发流控机制。一旦开始触发流控机制,则生产者的message生产,Broker的message推送将受到很大的影响.
流控一旦触发,RabbitMQ的性能将极大的恶化,消息推送也将很慢,直至资源使用恢复正常.
- 所以保证生产者,消费者的处理速度均衡很重要;而不至于由于消息堆积进而引发流控
总结
- RabbitMQ最大的优势,是丰富的message与queue的路由策略
- 由于RabbitMQ基于AMQP协议实现,所以其本身的实现方式是较重的
- RabbitMQ更加关注的是系统的可靠性,可用性;而不是系统的吞吐量(因为RabbitMQ是金融系统出生)