发现一篇宝藏文章,因为怕找不到所以copy过来,如若侵权请联系立即删除。
推荐大家可以去看看,一定有你需要的:>>>传送门<<<
一、概述
消息队列已经逐渐成为企业IT系统内部通信的核心手段,主要用来提升性能、系统解耦、流量消峰。 它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。
这里对比下RocketMQ和RabbitMQ,并总结常见问题的解决方式。
1.1 特性
RocketMQ:
- NameServer:整个MQ集群提供服务协调与治理,具体就是记录维护Topic、Broker的信息,及监控Broker的运行状态,Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步,相当于注册中心.
- Broker:消息服务器,作为server提供消息核心服务,每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server;
- Producer:消息生产者,业务的发起方,负责生产消息传输给broker.
- Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理
RabbitMQ:
- Exchange:交换机的作用就是根据路由规则,将消息转发到对应的队列上。.
- Broker:消息服务器,作为server提供消息核心服务
- Channel:信道是建立在真实的TCP连接内的虚拟连接.
- Routing key:生产者将消息发送到交换机时,会在消息头上携带一个 key,这个 key就是routing key,来指定这个消息的路由规则。
- Binding key:在绑定Exchange与Queue时,一般会指定一个binding key,生产者将消息发送给Exchange时,消息头上会携带一个routing key,当binding key与routing key相匹配时,消息将会被路由到对应的Queue中。
1.2 重复消费
正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除; 但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。
保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;
1.3 丢失数据
RocketMQ:
- 生产者丢数据:(1)采取send()同步发消息,发送结果是同步感知的。发送失败后可以重试,设置重试次数。默认3次。(2)发送失败的消息会存储在Commitlog中。
- 消息队列丢数据:(1)消息支持持久化到Commitlog里面,即使宕机后重启,未消费的消息也是可以加载出来的;(2)Broker自身支持同步刷盘、异步刷盘的策略,可以保证接收到的消息一定存储在本地的内存中;(3)Broker集群支持 1主N从的策略,支持同步复制和异步复制的方式,同步复制可以保证即使Master 磁盘崩溃,消息仍然不会丢失
- 消费者丢失数据:(1)完全成功后发送ACK;(2)维护一个持久化的offset
RabbitMQ:
- 生产者丢数据:RabbitMQ提供transaction(事务,支持回滚)和confirm模式(ACK给生产者)来确保生产者不丢消息;
- 消息队列丢数据:开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘,持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack。
- 消费者丢失数据:消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息,处理消息成功后,手动回复确认消息。
1.4 消费顺序
主要思路有两种:1、单线程消费来保证消息的顺序性;2、对消息进行编号,消费者处理时根据编号判断顺序。
每个queue的数据本身就是有序的,只要消费者这边有序消费,那么可以保证数据被顺序消费。如果是多线程消费,就要consumer内部用内存队列做排队。
1.5 高可用
RocketMQ:
- 多Master:配置简单,性能最高,但可能会有少量消息丢失(配置相关),单台机器重启或宕机期间,该机器下未被消费的消息在机器恢复前不可订阅,影响消息实时性
- 多Master多Slave异步模式:每个Master配一个Slave,有多对Master-Slave,消息写入全部是发送到Master Broker的,获取消息也可以Master获取,少了Slave Broker,会导致所有读写压力都集中在Master Broker,集群采用异步复制方式,主备有短暂消息延迟,毫秒级;性能同多Master几乎一样,实时性高,主备间切换对应用透明,不需人工干预,但Master宕机或磁盘损坏时会有少量消息丢失;
- 多Master多Slave同步模式:每个Master配一个Slave,有多对Master-Slave,消息写入全部是发送到Master Broker的,获取消息也可以Master获取,少了Slave Broker,会导致所有读写压力都集中在Master Broker,集群采用同步双写方式,主备都写成功,向应用返回成功;优点是服务可用性与数据可用性非常高;缺点是性能比异步集群略低,当前版本主宕备不能自动切换为主。
RabbitMQ:
- 普通集群模式:多台机器上启动多个rabbitmq实例,每个机器启动一个。但是你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据。完了你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。如果那个放queue的实例宕机了,会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化,让rabbitmq落地存储消息的话,消息不一定会丢,得等这个实例恢复了,然后才可以继续从这个queue拉取数据。
- 镜像集群模式:创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。缺点:(1)性能开销大,因为需要进行整个集群内部所有实例的数据同步;(2)无法线性扩容: 因为每一个服务器中都包含整个集群服务节点中的所有数据, 这样如果一旦单个服务器节点的容量无法容纳了。