和 Kafka 只支持同一个 Partition 内消息的顺序性一样,RocketMQ 中也提供了基于队列(分区)的顺序消费。即同一个队列内的消息可以做到有序,但是不同队列内的消息是无序的
需要从 Product 发送消息顺序,broker 中的 Queue 的接收顺序,Consumer 消费的顺序三个方面来保证。
如何保证 Product 发送消息顺序?
Apache RocketMQ 通过生产者和服务端的协议保障单个生产者串行地发送消息,并按序存储和持久化。
如需保证消息生产的顺序性,则必须满足以下条件:
- 单一生产者:消息生产的顺序性仅支持单一生产者,不同生产者分布在不同的系统,即使设置相同的消息组,不同生产者之间产生的消息也无法判定其先后顺序。
- 串行发送(同步发送):Apache RocketMQ 生产者客户端支持多线程安全访问,但如果生产者使用多线程并行发送,则不同线程间产生的消息将无法判定其先后顺序。
如何保证 Queue 中数据的顺序?
当我们作为MQ的生产者需要发送顺序消息时,需要在 send 方法中,传入一个 MessageQueueSelector
MessageQueueSelector 中需要实现一个select方法,这个方法就是用来定义要把消息发送到哪个MessageQueue 的,通常可以使用取模法进行路由:
SendResult sendResult = producer.send(msg, new MessageQueueSelector(){
@Override
//mqs:该Topic下所有可选的MessageQueue
//msg:待发送的消息
//arg:发送消息时传递的参数
public MessageQu