在RocketMQ中,顺序消息(Ordered Message)保证了消息在生产和消费时的顺序性。RocketMQ通过分区顺序(Partition Order)来实现这一点。消息按特定的顺序发送到同一个分区,消费时也是按相同的顺序从该分区读取消息。
RocketMQ 领域模型
消息生产
Apache RocketMQ 中用于产生消息的运行实体,一般集成于业务调用链路的上游。生产者是轻量级匿名无身份的。
消息存储
-
Apache RocketMQ 消息传输和存储的分组容器,主题内部由多个队列组成,消息的存储和水平扩展实际是通过主题内的队列实现的。
-
Apache RocketMQ 消息传输和存储的实际单元容器,类比于其他消息队列中的分区。 Apache RocketMQ 通过流式特性的无限队列结构来存储消息,消息在队列内具备顺序性存储特征。
-
Apache RocketMQ 的最小传输单元。消息具备不可变性,在初始化发送和完成存储后即不可变。
消息消费
-
Apache RocketMQ 发布订阅模型中定义的独立的消费身份分组,用于统一管理底层运行的多个消费者(Consumer)。同一个消费组的多个消费者必须保持消费逻辑和配置一致,共同分担该消费组订阅的消息,实现消费能力的水平扩展。
-
Apache RocketMQ 消费消息的运行实体,一般集成在业务调用链路的下游。消费者必须被指定到某一个消费组中。
-
Apache RocketMQ 发布订阅模型中消息过滤、重试、消费进度的规则配置。订阅关系以消费组粒度进行管理,消费组通过定义订阅关系控制指定消费组下的消费者如何实现消息过滤、消费重试及消费进度恢复等。
Apache RocketMQ 的订阅关系除过滤表达式之外都是持久化的,即服务端重启或请求断开,订阅关系依然保留。
1. 生产顺序消息
为了发送顺序消息,生产者需要指定消息的分区键,以确保同一键的消息发送到相同的分区。
syncSendOrderly(topic, message, hashKey)
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class RocketMQOrderProducer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
public void sendOrderlyMessage(String topic, String message, String hashKey) {
rocketMQTemplate.syncSendOrderly(topic, message, hashKey);
}
}
在这个例子中,hashKey
用来确定消息发送到哪个分区,确保具有相同hashKey
的消息按顺序发送。
2. 消费顺序消息
消费顺序消息时,需要确保消费者实例能够按顺序消费同一分区的消息。
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
@Service
@RocketMQMessageListener(topic = "your-topic", consumerGroup = "your-consumer-group")
public class OrderlyConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("Orderly Consumer received: " + message);
// Process the message
}
}