RocketMQ基本使用与编程实践
Maven依赖配置
在开始编写RocketMQ应用程序之前,需要在项目的pom.xml文件中添加RocketMQ客户端依赖:
<dependencies>
<!-- RocketMQ客户端依赖 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>5.1.4</version>
</dependency>
<!-- RocketMQ工具依赖(可选) -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-tools</artifactId>
<version>5.1.4</version>
</dependency>
</dependencies>
消息生产者(Producer)
1. 基本消息发送
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
public class SyncProducer {
public static void main(String[] args) throws Exception {
// 创建Producer实例,指定生产者组名
DefaultMQProducer producer = new DefaultMQProducer("producer_group_name");
// 设置NameServer地址
producer.setNamesrvAddr("localhost:9876");
// 启动Producer实例
producer.start();
for (int i = 0; i < 10; i++) {
// 创建消息对象,指定Topic、Tag和消息体
Message msg = new Message("TopicTest" /* Topic */,
"TagA" /* Tag */,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
);
// 发送消息并等待结果
SendResult sendResult = producer.send(msg);
System.out.printf("%s%n", sendResult);
}
// 关闭Producer实例
producer.shutdown();
}
}
2. 异步消息发送
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class AsyncProducer {
public static void main(String[] args) throws Exception {
// 创建Producer实例
DefaultMQProducer producer = new DefaultMQProducer("async_producer_group");
producer.setNamesrvAddr("localhost:9876");
producer.start();
// 设置发送失败时的重试次数
producer.setRetryTimesWhenSendAsyncFailed(0);
int messageCount = 10;
final CountDownLatch countDownLatch = new CountDownLatch(messageCount);
for (int i = 0; i < messageCount; i++) {
try {
final int index = i;
Message msg = new Message("TopicTest",
"TagB",
"OrderID188",
("Hello world" + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
// 异步发送消息
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.printf("%-10d OK %s %n", index,
sendResult.getMsgId());
countDownLatch.countDown();
}
@Override
public void onException(Throwable e) {
System.out.printf("%-10d Exception %s %n", index, e);
e.printStackTrace();
countDownLatch.countDown();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
// 等待所有异步消息发送完成
countDownLatch.await(5, TimeUnit.SECONDS);
producer.shutdown();
}
}
3. 单向消息发送
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
public class OnewayProducer {
public static void main(String[] args) throws Exception {
// 创建Producer实例
DefaultMQProducer producer = new DefaultMQProducer("oneway_producer_group");
producer.setNamesrvAddr("localhost:9876");
producer.start();
for (int i = 0; i < 10; i++) {
Message msg = new Message("TopicTest",
"TagC",
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
// 单向发送消息,不等待响应
producer.sendOneway(msg);
}
// 等待5秒以确保消息发送完成
Thread.sleep(5000);
producer.shutdown();
}
}
消息消费者(Consumer)
1. 推模式消费者(Push Consumer)
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import java.util.List;
public class PushConsumer {
public static void main(String[] args) throws Exception {
// 创建Consumer实例,指定消费者组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_group_name");
// 设置NameServer地址
consumer.setNamesrvAddr("localhost:9876");
// 订阅Topic和Tag
consumer.subscribe("TopicTest", "*");
// 注册消息监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
// 返回消费状态
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动Consumer实例
consumer.start();
System.out.printf("Consumer Started.%n");
// 保持程序运行
System.in.read();
}
}
2. 拉模式消费者(Pull Consumer)
import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
import org.apache.rocketmq.client.consumer.PullResult;
import org.apache.rocketmq.common.message.MessageQueue;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class PullConsumer {
private static final Map<MessageQueue, Long> offseTable = new HashMap<>();
public static void main(String[] args) throws Exception {
// 创建PullConsumer实例
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("pull_consumer_group");
consumer.setNamesrvAddr("localhost:9876");
consumer.start();
// 获取指定Topic的所有消息队列
Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues("TopicTest");
for (MessageQueue mq : mqs) {
System.out.printf("Consume from the queue: %s%n", mq);
SINGLE_MQ:
while (true) {
try {
// 拉取消息
PullResult pullResult =
consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
System.out.printf("%s%n", pullResult);
// 更新消费位置
putMessageQueueOffset(mq, pullResult.getNextBeginOffset());
switch (pullResult.getPullStatus()) {
case FOUND:
// 处理消息
dealWithPullResult(pullResult);
break;
case NO_MATCHED_MSG:
break;
case NO_NEW_MSG:
break SINGLE_MQ;
case OFFSET_ILLEGAL:
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
consumer.shutdown();
}
private static long getMessageQueueOffset(MessageQueue mq) {
Long offset = offseTable.get(mq);
if (offset != null)
return offset;
return 0;
}
private static void putMessageQueueOffset(MessageQueue mq, long offset) {
offseTable.put(mq, offset);
}
private static void dealWithPullResult(PullResult pullResult) {
if (pullResult.getMsgFoundList() != null) {
for (MessageExt msg : pullResult.getMsgFoundList()) {
System.out.printf("Received message: %s%n", new String(msg.getBody()));
}
}
}
}
消息类型详解
1. 普通消息
普通消息是最基本的消息类型,适用于大多数业务场景。
Message msg = new Message("TopicTest",
"TagA",
"KEY123",
"Hello RocketMQ".getBytes());
2. 顺序消息
顺序消息保证消息按照发送顺序被消费。
// 生产者端
public class OrderlyProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("orderly_producer_group");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String[] tags = new String[]{"TagA", "TagB", "TagC"};
for (int i = 0; i < 10; i++) {
int orderId = i % 3;
Message msg = new Message("OrderTopic", tags[orderId],
"KEY" + orderId,
("Hello RocketMQ " + i).getBytes());
// 发送顺序消息,使用orderId作为选择队列的参数
SendResult sendResult = producer.send(msg, (mqs, msg1, arg) -> {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}, orderId);
System.out.printf("%s%n", sendResult);
}
producer.shutdown();
}
}
// 消费者端
public class OrderlyConsumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("orderly_consumer_group");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("OrderTopic", "*");
// 注册顺序消息监听器
consumer.registerMessageListener((MessageListenerOrderly) (msgs, context) -> {
for (MessageExt msg : msgs) {
System.out.printf("Receive message: %s%n", new String(msg.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
});
consumer.start();
System.out.printf("Orderly Consumer Started.%n");
System.in.read();
}
}
3. 广播消息
广播消息会发送给同一消费者组内的所有消费者。
// 设置消费模式为广播模式
consumer.setMessageModel(MessageModel.BROADCASTING);
消息属性设置
Message msg = new Message("TopicTest",
"TagA",
"KEY123",
"Hello RocketMQ".getBytes());
// 设置延迟级别(1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h)
msg.setDelayTimeLevel(3); // 延迟10秒
// 设置自定义属性
msg.putUserProperty("property1", "value1");
msg.putUserProperty("property2", "value2");
// 设置消息键
msg.setKeys("KEY123");
小结
本章介绍了RocketMQ的基本使用方法,包括消息生产者和消费者的编程实践。我们学习了三种消息发送方式(同步、异步、单向)和两种消费模式(推模式、拉模式),以及顺序消息和广播消息的使用方法。
掌握了这些基础知识后,在下一章节中,我们将深入学习RocketMQ的高级特性,如事务消息、定时消息等。
1228

被折叠的 条评论
为什么被折叠?



