ActiveMQ、RabbitMQ、Kafka、RocketMQ的区别

ActiveMQ

老牌消息队列,是Java写的mq,但支持C,C++,PHP,python等各客户端,配置和使用基本上是Java xml这一套,同时对spring支持比较友好。在java程序中,也可以作为jar包放在java项目里面。
activemq支持主从复制,集群,但集群功能很弱,只支持failover,即连一个broker失败了,可以转到其他broker来,但这样有一个缺陷,当有三个broker的时,其中有一个是没有consumer的,但另外两个挂了,信息还是会存入到这个broker,然后会将消息不断堆积。

acticemq只支持两个模式 queue 和 topic

queue

也就是多对一的通信,producer 将消息传入queue里面,consumer去queue里面取消息,这里它还有messageGroup的概念,也就是消费者组,当一个消费者消费不够快时,可以将多个消费者放入一个messageGroup,queue会轮流发给组里的消费者,每个消息只会消费一次。

topic

广播,producer发布带有topic标示的消息,消费者订阅感兴趣的topic,所有订阅了topic的消费者都会收到消息。订阅分为持久和不持久。持久订阅,当消费者断开一段时间再连上了,中间的消息会发送给消费者。不持久的话,消费者断开那段时间的消息是不会发给消费者的。

RabbitMQ

rabbitMQ是用erlang写的,功能比activeMQ多,有实例,用户权限,监控系统,当然也更复杂。
从机制上讲,rabbitMQ也有queue,topic的概念,但其多了一个概念叫交换机,一条消息的传播过程为producer->exchang->queue->consumer , 生产者发送的信息都会带有key表示发送给哪一个交换机,再由交换机发送给队列。

交换机有四种 direct fanout topic header

direct

直连交换机,与该交换机绑定的队列都会绑定一个routingKey,交换机会根据生产者发送的消息里的routingKey转发给相应的队列。
比如有一个直连交换机 direct1 ,4个队列 queue1,queue2,queue3,queue4,其中queue1 与 queue2绑定keya,queue3和queue4绑定keyb,。交换机在收到带有keya的消息时,会发送给queue1与queue2。收到keyb的消息时,会发送给queue3和queue4。

fanout

扇形交换机,也就是广播,该交换机接收到的消息会发送给与它绑定的所有队列。
总体来说,fanout就是direct实现的,当绑定到交换机的队列的key一样时,direct也就成了fanout。

topic

主题交换机,与direct比,多了一个通配符匹配规则,队列和交换机绑定key需要采用*.#…的格式。单词间用.分隔开
*代表一个单词,#代表多个单词
比如有四条队列绑定的key分别为 bat.# , .man.super.man, #.supper.,#.man
那么当发送一条key为bat.man.super.man的消息时,这四条队列都会收到消息。

header

首部交换机,这个交换机很少使用到,其忽略了routingKey,而是根据发送的消息内容中的headers属性进行匹配。

Kafka

kafka是一个分布式流处理平台,可以发布,订阅流式记录,存储流式记录,在记录产生时进行处理。
它可以用于两大类别的应用:
构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (相当于message queue)
构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化)

先理解kafka的一些名词角色。

  • producer 生产者,向kafka的broker发送消息的客户端
  • consumer 消费者,从broker拉取消息
  • consumerGroup 消费者组,所有消费者都属于一个消费者组,消费组是逻辑上的订阅者
  • broker 一个kafka服务就是一个broker
  • topic 主题,kafka的消息以topic分类,消费者组会指定要消费的topic,一个消费者可以消费多个topic,一个topic可以被多个消费者消费。
  • partition 分区,一个topic的消息可以分为多个分区存储,一个分区的消息只能由同一个消费组里的一个消费者消费,但同一个组的消费者可以消费多个分区。
  • replication 副本,kafka集群中,每一个分区有多个副本,每一个broker中每一个分区只有一个副本。
  • leader 主副本,消息的生产和消费都是与主副本来交互的,产生与消费的消息会同步给从副本。
  • flower 从副本,当主副本宕机时,会在从副本中选举一个作为主副本。
  • controller kafka集群中用来进行选举的一个broker。
  • message 消息主体
  • offset 消费者消费偏移量,由消费者维护,但存储在broker中

所有消息都有一个topic,消费组和topic为多对多关系,topic和分区为一对多关系,consumer 和分区为一对多关系。
生产者发送消息时,并非一条消息发送一次,而是默认等数据到16k或者消息超过10ms时,发送一次。消息到服务端后,会将消息以追加的方式写入文件,os pageCache和顺序io使得写入消息的性能非常高,速度相当于内存写。
消费者拉取数据时,消息从磁盘发送采用sendfile的零拷贝方式,DMA将数据从磁盘读取到内核空间后,将数据的位置、长度等描述符复制到用户空间以及socket缓冲区,然后DMA将数据从内核空间直接传递给引擎协议。
服务端存储数据时,以log追加的方式存储,为了避免数据过大导致的查询时间过长,采用了分片和索引机制,将一个分区分成多个segment,每个segment下存在索引文件与数据文件,索引文件的元数据就是数据文件的偏移地址。每一个分区的文件存在同一个文件夹里面,文件夹命名方式为topic-分区号。索引文件和数据文件的命名方式为该segment的第一个消息的offset。

消息重复与丢失

要做到消息不重复消费,不丢失消息,一般从三个地方入手。生产者 服务端 消费者

生产者

kafka生产者的acks方式有三种:

  • 0 消息发送之后,不等待broker应答
  • -1 消息发送之后,等待leader broker以及其ISR列表(与leader保持同步的follower列表)写入成功,才返回成功
  • 1 默认值,当leader写入成功后,返回成功
    在默认值1中,当集群没有出现问题时,做到了消息不丢失,但可以由于网络原因,生产者重复发送消息导致消息重复。
    kafka0.11版引入了idempotent producer机制,当设置值为true时,broker为每一条消息根据编号去重,以此可以实现生产者的exactly once.
服务端

服务端保证消息不丢失,也就是消息持久化。kafka采用副本的方式来保证消息不丢失。

消费者

消费者靠offset保证消息的传递。
当消费者开启enable.auto.commit时,消费者取到消息后,就自动提交offset。
不开启时,当消息消费完成之后,才会提交,这就保证了消息不会丢失消费,但可能重复消费,这就需要在业务层面来保证消息的幂等性。

RocketMQ

RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,前身是MetaQ,
是阿里参考Kafka特点研发的一个队列模型的消息中间件,
后开源给apache基金会成为了apache的顶级开源项目,具有高性能、高可靠、高实时、分布式特点。

性能对照表

特性ActiveMQRabbitMQKafkaRocketMQ
开发语言javaerlangscalajava
单机吞吐量万级万级10万级(可接近100万)10万级
时效性ms级us级ms级以内ms级
可用性高(主从架构)高(主从架构)非常高(分布式架构)非常高(分布式架构)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值