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();
}
}
}