Springboot+RocketMQ+消息顺序发送与顺序消费及其事务控制

消息顺序发送

消息有序指的是可以按照消息的发送顺序来消费。
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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值