当rabbitmq队列拥有多个消费者的时候,队列收到的消息将以轮询的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复。
这种方式非常适合扩展,而且是专门为并发程序设计的。
如果某些消费者的任务比较繁重,那么可以设置basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,rabbitmq不再向这个消费者发送任何消息。
zeromq:点对点(p2p)
rocketmq:基于topic/messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式
【发送】
发送消息通过轮询队列的方式发送,每个队列接收平均的消息量。发送消息指定topic、tags、keys,无法指定投递到哪个队列(没有意义,集群消费和广播消费跟消息存放在哪个队列没有关系)。
tags选填,类似于 Gmail 为每封邮件设置的标签,方便服务器过滤使用。目前只支 持每个消息设置一个 tag,所以也可以类比为 Notify 的 MessageType 概念。
keys选填,代表这条消息的业务关键词,服务器会根据 keys 创建哈希索引,设置后, 可以在 Console 系统根据 Topic、Keys 来查询消息,由于是哈希索引,请尽可能 保证 key 唯一,例如订单号,商品 Id 等。
【接收】
1>广播消费。一条消息被多个Consumer消费,即使Consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次。
2>集群消费。一个 Consumer Group中的Consumer实例平均分摊消费消息。例如某个Topic有 9 条消息,其中一个Consumer Group有3个实例,那么每个实例只消费其中的 3 条消息。即每一个队列都把消息轮流分发给每个consumer。
activemq:点对点(p2p)、广播(发布-订阅)
点对点模式,每个消息只有1个消费者;
发布/订阅模式,每个消息可以有多个消费者。
【发送】
点对点模式:先要指定一个队列,这个队列会被创建或者已经被创建。
发布/订阅模式:先要指定一个topic,这个topic会被创建或者已经被创建。
【接收】
点对点模式:对于已经创建了的队列,消费端要指定从哪一个队列接收消息。
发布/订阅模式:对于已经创建了的topic,消费端要指定订阅哪一个topic的消息。
十三、顺序消息Kafka:支持。
设置生产者的max.in.flight.requests.per.connection为1,可以保证消息是按照发送顺序写入服务器的,即使发生了重试。
kafka保证同一个分区里的消息是有序的,但是这种有序分两种情况
1>key为null,消息逐个被写入不同主机的分区中,但是对于每个分区依然是有序的
2>key不为null , 消息被写入到同一个分区,这个分区的消息都是有序。
rabbitmq:不支持
zeromq:不支持
rocketmq:支持
activemq:不支持
十四、消息确认Kafka:支持。
1>发送方确认机制
ack=0,不管消息是否成功写入分区
ack=1,消息成功写入首领分区后,返回成功
ack=all,消息成功写入所有分区后,返回成功。
2>接收方确认机制
自动或者手动提交分区偏移量,早期版本的kafka偏移量是提交给Zookeeper的,这样使得zookeeper的压力比较大,更新版本的kafka的偏移量是提交给kafka服务器的,不再依赖于zookeeper群组,集群的性能更加稳定。
rabbitmq:支持。
1>发送方确认机制,消息被投递到所有匹配的队列后,返回成功。如果消息和队列是可持久化的,那么在写入磁盘后,返回成功。支持批量确认和异步确认。
2>接收方确认机制,设置autoAck为false,需要显式确认,设置autoAck为true,自动确认。
当autoAck为false的时候,rabbitmq队列会分成两部分,一部分是等待投递给consumer的消息,一部分是已经投递但是没收到确认的消息。如果一直没有收到确认信号,并且consumer已经断开连接,rabbitmq会安排这个消息重新进入队列,投递给原来的消费者或者下一个消费者。
未确认的消息不会有过期时间,如果一直没有确认,并且没有断开连接,rabbitmq会一直等待,rabbitmq允许一条消息处理的时间可以很久很久。
zeromq:支持。
rocketmq:支持。
activemq:支持。
十五、消息回溯Kafka:支持指定分区offset位置的回溯。 rabbitmq:不支持 zeromq:不支持 rocketmq:支持指定时间点的回溯。 activemq:不支持
十六、消息重试Kafka:不支持,但是可以实现。
kafka支持指定分区offset位置的回溯,可以实现消息重试。
rabbitmq:不支持,但是可以利用消息确认机制实现。
rabbitmq接收方确认机制,设置autoAck为false。