消息顺序发送
消息有序指的是可以按照消息的发送顺序来消费。
RocketMQ可以严格的保证消息有序。但这个顺序,不是全局顺序,只是分区(queue)顺序。要全局顺序只能一个分区。
之所以出现你这个场景看起来不是顺序的,是因为发送消息的时候,消息发送默认是会采用轮询的方式发送到不通的queue(分区)。如图:
话不多说看代码:
首先是顺序消息的生产者
package com.rocketmq.rocketmq.mq.order;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import java.io.UnsupportedEncodingException;
import java.util.List;
/**
* author wyt 2019-12-10
* 按一定顺序发消息
*/
public class OrderProducer {
public static void main(String[] args) throws MQClientException, UnsupportedEncodingException, RemotingException, InterruptedException, MQBrokerException {
//1.创建消息生产者
DefaultMQProducer defaultMQProducer=new DefaultMQProducer("demo_producer_group");//指定消息发送组
//2.设置Nameser 的地址
defaultMQProducer.setNamesrvAddr("localhost:9876");
//3.开启defaultMQProducer
defaultMQProducer.start();//此处有异常需要抛出
//5.发送消息(顺序发消息 需要制定消息队列 不认无法保持顺序)
//第一个参数是发送的消息信息
//第二个参数是选中指定的消息队列对象(会传入所有的消息队列)
//第三个参数是指定对应的消息队列的下标
/**
* 循环多次发送验证
*/
for (int i = 0; i <6 ; i++) {
//4.创建新消息
//注意选择 导入这个包的:org.apache.rocketmq.common.message.Message;
//public Message(String topic, String tags, String keys, byte[] body)
//body:就是你需要发送的消息
//RemotingHelper.DEFAULT_CHARSET 设置UTF_8的编码格式
Message message =new Message(
"Topic_Order_Demo",//topic:主题
"Tags_Order_Demo",//tags:标签(主要用于消息过滤作用)
"Keys_Order_1",//消息的唯一值
("hello_Order!"+i).getBytes(RemotingHelper.DEFAULT_CHARSET)); //body:就是你需要发送的消息
SendResult result = defaultMQProducer.send(
message,
new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
//你想要的指定的队列的下标 就是下面的数值1
Integer index=(Integer) o;
//返回队列
return list.get(index);
}
},
1
);
System.out.println("Order有序消息发送结果 :"+result);
}
//6.关闭消息发送对像
defaultMQProducer.shutdown();
}
}
在这里我循环发送多条消息:
Order有序消息发送结果 :SendResult [sendStatus=SEND_OK, msgId=C0A801E1302818B4AAC231F59F020000, offsetMsgId=C0A801E100002A9F0000000000002184, messageQueue=MessageQueue [topic=Topic_Order_Demo, brokerName=USER-20170315QN, queueId=1], queueOffset=30]
Order有序消息发送结果 :SendResult [sendStatus=SEND_OK, msgId=C0A801E1302818B4AAC231F59F1C0001, offsetMsgId=C0A801E100002A9F0000000000002257, messageQueue=MessageQueue [topic=Topic_Order_Demo, brokerName=USER-2017031