RocketMQ顺序消息

RocketMQ消息发送基本示例(推送消费者)-CSDN博客

RocketMQ消费者主动拉取消息示例-CSDN博客

顺序消息指生产者局部有序发送到一个Queue,但是注意,多个Queue之间是全局无序的

如果生产者将先发送消息1到 队列1 后发送消息2到队列2 消费者不一定先接收到消息1 可能先接收到消息2

顺序消息生产者示例:通过MessageQueueSelector将消息有序发送到同一个queue中

顺序消息消费者示例:通过MessageListenerOrderly消费者每次读取消息都只从一个Queue中获取(通过加锁的方法实现)

package com.example.rocketmqdemo.order;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.List;

/**
 * 顺序消费的消费者示例
 * 该类展示了如何使用RocketMQ进行顺序消息的消费
 * 通过使用MessageListenerOrderly接口,保证消息的顺序性消费
 *
 * @date 2024/8/1 1:40
 */
public class OrderConsumer {
    public static void main(String[] args) {
        //创建一个DefaultMQPushConsumer实例,指定消费者组名为"order_consumer_group"
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("order_consumer_group");
        //设置NameServer地址,RocketMQ客户端通过NameServer获取Broker的路由信息
        consumer.setNamesrvAddr("xxx.xxx.xxx:9876");
        try {
            //订阅指定的主题和标签,这里使用"*"表示订阅所有标签
            consumer.subscribe("order_topic", "*");

            //设置顺序消息的消息监听器
            consumer.setMessageListener(new MessageListenerOrderly() {
                @Override
                public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext context) {
                    //遍历接收到的消息列表
                    for (int i = 0; i < list.size(); i++) {
                        System.out.println(i + "_消息消费成功_" + new String(list.get(i).getBody()));
                    }
                    // 返回消费状态,SUCCESS表示消息消费成功
                    return ConsumeOrderlyStatus.SUCCESS;
                }
            });

            // 也可以使用并发消费的方式
            // consumer.setMessageListener(new MessageListenerConcurrently() {
            //     @Override
            //     public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {
            //         System.out.println(Thread.currentThread().getName());
            //         for (int i = 0; i < list.size(); i++) {
            //             System.out.println(i + "_消息消费成功_" + new String(list.get(i).getBody()));
            //         }
            //         return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            //     }
            // });

            //启动消费者实例
            consumer.start();
        } catch (Exception e) {
            //捕获并打印异常信息
            e.printStackTrace();
        }
    }
}

package com.example.rocketmqdemo.order;

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 java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 顺序消息的生产者示例
 * 该类演示了如何使用 RocketMQ 生产顺序消息
 * 生产的消息将按照顺序被发送到指定的队列
 *
 * @author hrui
 * @date 2024/8/1 1:26
 */
public class OrderProducer {
    public static void main(String[] args) {
        //创建一个DefaultMQProducer实例,指定生产者组名为"order_producer_group"
        DefaultMQProducer producer = new DefaultMQProducer("order_producer_group");
        //设置NameServer地址,RocketMQ客户端通过NameServer获取Broker的路由信息
        producer.setNamesrvAddr("xxx.xxx.xxx:9876");

        try {
            //启动生产者实例
            producer.start();

            //模拟发送5个订单,每个订单包含10个步骤的消息
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 10; j++){
                    //创建消息实例,指定主题、标签和消息内容
                    Message message = new Message("order_topic", "tag_order", ("order_" + i + "_step_" + j).getBytes(StandardCharsets.UTF_8));

                    //使用自定义的MessageQueueSelector来选择队列
                    SendResult sendResult = producer.send(message, new MessageQueueSelector() {
                        @Override
                        public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
                            //通过订单ID来选择队列,保证同一订单的消息发送到相同的队列
                            Integer id = (Integer) o;
                            int index = id % list.size(); //选择队列的算法:订单ID取模队列数量
                            return list.get(index);
                        }
                    }, i); //参数i作为订单ID传入,保证同一订单的消息按顺序发送到相同的队列

                    //打印消息发送结果
                    System.out.println("消息发送成功_" + sendResult);
                }
            }
        } catch (Exception e) {
            //捕获并打印异常信息
            e.printStackTrace();
        } finally {
            //关闭生产者实例,释放资源
            producer.shutdown();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hrui0706

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值