RocketMQ顺序消息
实现原理
生产者将需要排序的消息发送到指定的MessageQueue;
消费者需要配置一个队列,一个线程消费;
只能保证局部有序,不能保证全局有序。
注意点
- Broker的数量就是Topic下的MessageQueue的最小数量,一般线上环境Broker都是多个,所以无法将MessageQueue的数量配置成1个。
- RocketMQTemplate不支持将消息发送到特定的队列,可以使用API
rocketMQTemplate#getProducer()
获取原生生产者对象。
生产者
public class Producer {
public static void main(String[] args) throws UnsupportedEncodingException {
try {
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
// producer.setNamesrvAddr("127.0.0.0:9876");
producer.start();
for (int i = 0; i < 10; i++) {
int orderId = i;
for(int j = 0 ; j <= 5 ; j ++){
Message msg =
new Message("OrderTopicTest", "order_"+orderId, "KEY" + orderId,
("order_"+orderId+" step " + j).getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}
}, orderId);
System.out.printf("%s%n", sendResult);
}
}
producer.shutdown();
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
e.printStackTrace();
}
}
}
消费者
@Component
@RocketMQMessageListener(
consumerGroup = "${rocketmq.techbase.consumer.process-center-approval-group}",
topic = "${rocketmq.techbase.consumer.process-center-approval-topic}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.techbase.name-server}",
secretKey = "${rocketmq.techbase.consumer.secret-key}",
accessKey = "${rocketmq.techbase.consumer.access-key}"
)
public class OrderlyConsumer implements RocketMQListener<MessageExt>{}