RocketMQ和RabbitMQ的区别

发布时间 2023-07-11 01:05:21作者: huigui_mint

一、概述

消息队列已经逐渐成为企业IT系统内部通信的核心手段,主要用来提升性能、系统解耦、流量消峰。 它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。

这里对比下RocketMQ和RabbitMQ,并总结常见问题的解决方式。

1.1 特性

RocketMQ:

  1. NameServer:整个MQ集群提供服务协调与治理,具体就是记录维护Topic、Broker的信息,及监控Broker的运行状态,Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步,相当于注册中心.
  2. Broker:消息服务器,作为server提供消息核心服务,每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server;
  3. Producer:消息生产者,业务的发起方,负责生产消息传输给broker.
  4. Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理

RabbitMQ:

  1. Exchange:交换机的作用就是根据路由规则,将消息转发到对应的队列上。.
  2. Broker:消息服务器,作为server提供消息核心服务
  3. Channel:信道是建立在真实的TCP连接内的虚拟连接.
  4. Routing key:生产者将消息发送到交换机时,会在消息头上携带一个 key,这个 key就是routing key,来指定这个消息的路由规则。
  5. Binding key:在绑定Exchange与Queue时,一般会指定一个binding key,生产者将消息发送给Exchange时,消息头上会携带一个routing key,当binding key与routing key相匹配时,消息将会被路由到对应的Queue中。

1.2 重复消费

正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除; 但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。

保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;

1.3 丢失数据

RocketMQ:

  1. 生产者丢数据:(1)采取send()同步发消息,发送结果是同步感知的。发送失败后可以重试,设置重试次数。默认3次。(2)发送失败的消息会存储在Commitlog中。
  2. 消息队列丢数据:(1)消息支持持久化到Commitlog里面,即使宕机后重启,未消费的消息也是可以加载出来的;(2)Broker自身支持同步刷盘、异步刷盘的策略,可以保证接收到的消息一定存储在本地的内存中;(3)Broker集群支持 1主N从的策略,支持同步复制和异步复制的方式,同步复制可以保证即使Master 磁盘崩溃,消息仍然不会丢失
  3. 消费者丢失数据:(1)完全成功后发送ACK;(2)维护一个持久化的offset

RabbitMQ:

  1. 生产者丢数据:RabbitMQ提供transaction(事务,支持回滚)和confirm模式(ACK给生产者)来确保生产者不丢消息;
  2. 消息队列丢数据:开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘,持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack。
  3. 消费者丢失数据:消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息,处理消息成功后,手动回复确认消息。

1.4 消费顺序

主要思路有两种:1、单线程消费来保证消息的顺序性;2、对消息进行编号,消费者处理时根据编号判断顺序。

每个queue的数据本身就是有序的,只要消费者这边有序消费,那么可以保证数据被顺序消费。如果是多线程消费,就要consumer内部用内存队列做排队。

1.5 高可用

RocketMQ:

  1. 多Master:配置简单,性能最高,但可能会有少量消息丢失(配置相关),单台机器重启或宕机期间,该机器下未被消费的消息在机器恢复前不可订阅,影响消息实时性
  2. 多Master多Slave异步模式:每个Master配一个Slave,有多对Master-Slave,消息写入全部是发送到Master Broker的,获取消息也可以Master获取,少了Slave Broker,会导致所有读写压力都集中在Master Broker,集群采用异步复制方式,主备有短暂消息延迟,毫秒级;性能同多Master几乎一样,实时性高,主备间切换对应用透明,不需人工干预,但Master宕机或磁盘损坏时会有少量消息丢失;
  3. 多Master多Slave同步模式:每个Master配一个Slave,有多对Master-Slave,消息写入全部是发送到Master Broker的,获取消息也可以Master获取,少了Slave Broker,会导致所有读写压力都集中在Master Broker,集群采用同步双写方式,主备都写成功,向应用返回成功;优点是服务可用性与数据可用性非常高;缺点是性能比异步集群略低,当前版本主宕备不能自动切换为主。

RabbitMQ:

  1. 普通集群模式:多台机器上启动多个rabbitmq实例,每个机器启动一个。但是你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据。完了你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。如果那个放queue的实例宕机了,会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化,让rabbitmq落地存储消息的话,消息不一定会丢,得等这个实例恢复了,然后才可以继续从这个queue拉取数据。
  2. 镜像集群模式:创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。缺点:(1)性能开销大,因为需要进行整个集群内部所有实例的数据同步;(2)无法线性扩容: 因为每一个服务器中都包含整个集群服务节点中的所有数据, 这样如果一旦单个服务器节点的容量无法容纳了。