RocketMQ是一款由阿里云开发的分布式开源消息中间件,广泛应用于各种数据传输和处理场景。本文将带你初步了解RocketMQ的核心概念、优势和应用场景,帮助你快速上手使用。RocketMQ支持高吞吐量、实时性和可靠性,适用于大数据、金融和日志采集等多个领域。RocketMQ初识学习将涵盖从环境搭建到基本消息发送与接收的全过程。
RocketMQ简介 RocketMQ是什么RocketMQ是由阿里云开发的一款分布式开源消息中间件,它基于JMS(Java Message Service)标准,具有高吞吐量、稳定可靠、实时性好等特点。RocketMQ广泛应用于大数据场景、互联网金融、日志采集与处理、分布式事务处理等领域。
RocketMQ采用分布式架构设计,可以支持集群模式和单机模式部署。此外,RocketMQ还支持多种消息发送方式以及消息过滤功能,具有强大的消息路由机制。
RocketMQ的核心概念在理解RocketMQ之前,需要先熟悉几个核心概念:
- Broker:RocketMQ的Broker是消息队列的管理节点,它负责接收生产者发送的消息并将消息转发给相应的消费者。Broker也是消息的存储节点,负责持久化消息。
- Producer:生产者负责发送消息到Broker。生产者可以通过网络与Broker通信,将消息发送到指定的主题(Topic)。
- Consumer:消费者负责接收Broker中存储的消息。消费者可以通过网络与Broker通信,从指定的主题中获取消息。
- Topic:主题是RocketMQ中消息分类的标识,通常对应一个业务逻辑。生产者发送消息时需要指定发送到哪个主题。
- Queue:队列是主题的逻辑表示。每个主题可以包含多个队列,每个队列都有唯一的ID。
- Message:消息是RocketMQ的基本传输单元,包括消息体、消息头(Message Header)等信息。消息还可以设置消息键(Message Key)、标签(Tag)等属性,以方便消息的路由和过滤。
- Consumer Group:消费者组是一组逻辑上的消费者实例,它们共同消费同一个主题的消息。RocketMQ支持集群模式和广播模式两种消费模式。
- Clustering:集群模式下,同一个消费者组内的所有消费者实例共同消费同一份消息,每个消息只会被消费一次。
- Broadcasting:广播模式下,同一个消费者组内的每个消费者实例都会接收到消息的全部副本。
优势
- 高吞吐量:RocketMQ支持每秒百万级别的消息传输。
- 可靠性:RocketMQ支持事务消息、顺序消息和幂等消费等特性,保证消息的可靠传输。
- 实时性:RocketMQ支持毫秒级延迟的消息传输。
- 扩展性:RocketMQ支持集群模式,可以方便地扩展到多个节点,支持水平扩展和垂直扩展。
- 容错性:RocketMQ具有高可用性,支持主备切换和故障转移,保证消息不丢失。
- 消息过滤和路由:RocketMQ支持基于标签(Tag)、消息键(Message Key)等多种方式的消息过滤,提供灵活的消息路由机制。
- 消息轨迹:RocketMQ提供了消息轨迹查询功能,可以方便地追踪消息的发送和接收过程。
应用场景
- 大数据场景:RocketMQ可以用于实时数据采集、数据传输和处理。
- 互联网金融:RocketMQ可以用于交易日志记录、账单通知、支付和退款等场景。
- 日志采集与处理:RocketMQ可以用于日志收集、分析和容错。
- 分布式事务处理:RocketMQ支持事务消息和顺序消息,可以用于分布式事务处理。
- 微服务架构:RocketMQ可以作为微服务之间的消息通信中介,实现服务间解耦和异步通信。
- 消息队列:RocketMQ可以作为系统之间的消息中间件,实现消息的可靠传输和处理。
RocketMQ基于Java开发,因此首先需要安装Java开发环境。
- 访问Oracle官网下载最新的JDK版本:Oracle JDK下载页面。
- 根据操作系统(Windows、Linux、MacOS)下载相应的JDK安装包。
- 安装JDK,设置环境变量。在命令行中输入
java -version
,确认Java环境安装正确。 - 下载并安装Maven,用于构建RocketMQ项目。从Maven官网下载最新版本:Maven下载页面。
- 解压Maven到指定目录,并设置环境变量。
export JAVA_HOME=/path/to/jdk
export PATH=$JAVA_HOME/bin:$PATH
export MAVEN_HOME=/path/to/maven
export PATH=$MAVEN_HOME/bin:$PATH
下载并安装RocketMQ
- 访问阿里云RocketMQ官网下载最新版本的RocketMQ:RocketMQ下载页面。
- 解压下载的RocketMQ压缩包到指定目录。
- 设置环境变量。编辑
~/.bashrc
文件,添加RocketMQ的路径:
export ROCKETMQ_HOME=/path/to/rocketmq
export PATH=$ROCKETMQ_HOME/bin:$PATH
- 刷新环境变量:
source ~/.bashrc
配置RocketMQ环境变量
- 编辑RocketMQ的配置文件
conf/standalone.conf
,根据需要修改Broker、NameServer等配置。 - 重启系统,使环境变量生效。
- 进入RocketMQ的
bin
目录。 - 启动NameServer:
./mqnamesrv &
- 启动Broker:
./mqbroker -n localhost:9876 -c ../conf/standalone.conf &
- 查看RocketMQ运行状态:
```bash.
./mqadmin brokerList -n localhost:9876
# RocketMQ基本概念与术语
## 消息模型
RocketMQ的消息模型分为发布-订阅模型(Publish/Subscribe)和点对点模型(Point-to-Point)。
- **发布-订阅模型**:生产者将消息发布到一个主题(Topic),多个消费者可以订阅该主题的消息。每个消息只会被一个消费者处理。
- **点对点模型**:生产者将消息发布到一个队列(Queue),消费者从该队列中接收消息。每个消息只会被一个消费者处理。
### 代码示例
```java
// 发布-订阅模型
public void sendMessage(String topic) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
// 点对点模型
public void sendMessage(String queue) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(queue, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
消费者与生产者
- 生产者(Producer):生产者负责发送消息。生产者通过网络与Broker通信,将消息发送到指定的主题。
- 消费者(Consumer):消费者负责接收消息。消费者通过网络与Broker通信,从指定的主题中获取消息。
代码示例
// 生产者发送消息
public void sendMessage(String topic) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
// 消费者接收消息
public void consumeMessage(String topic) {
Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe(topic, "*");
consumer.setMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.println("Received message: " + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
主题与队列
- 主题(Topic):主题是消息分类的标识,通常对应一个业务逻辑。生产者发送消息时需要指定发送到哪个主题。
- 队列(Queue):主题可以包含多个队列,每个队列都有唯一的ID。队列用于存储和转发消息。
代码示例
// 发送消息到主题
public void sendMessage(String topic) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
// 发送消息到队列
public void sendMessage(String queue) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(queue, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
消息发送与接收
- 发送消息:生产者发送消息到Broker,Broker将消息存储在主题对应的队列中。
- 接收消息:消费者从Broker中接收消息,Broker将消息从队列中取出并发送给消费者。
代码示例
// 生产者发送消息
public void sendMessage(String topic) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9ibli79876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
// 消费者接收消息
public void consumeMessage(String topic) {
Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe(topic, "*");
consumer.setMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.println("Received message: " + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
消息过滤与路由
- 消息过滤:通过设置标签(Tag)、消息键(Message Key)等方式过滤消息。
- 消息路由:根据主题、队列等信息将消息路由到相应的消费者。
代码示例
// 发送消息并设置标签
public void sendMessage(String topic, String tag) {
Producer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, tag, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
// 接收消息并根据标签过滤
public void consumeMessage(String topic, String tag) {
Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe(topic, tag);
consumer.setMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.println("Received message: " + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
RocketMQ消息发送与接收
发送消息的步骤
- 创建生产者实例。
- 设置生产者的属性,例如消息发送超时时间等。
- 创建消息对象,设置消息的属性(主题、消息体等)。
- 发送消息到Broker。
代码示例:
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
public class Producer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "TestTopic";
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
}
接收消息的步骤
- 创建消费者实例。
- 设置消费者属性,例如消费模式(集群模式、广播模式)等。
- 消费者订阅指定的主题。
- 消费者接收并处理消息。
代码示例:
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
public class Consumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TestTopic", "*");
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
System.out.println(new String(msg.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
发送同步与异步消息
- 同步消息:生产者发送消息后等待Broker返回结果,确保消息发送成功。
- 异步消息:生产者发送消息后不再等待Broker返回结果,而是通过回调函数异步处理结果。
代码示例:
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
public class AsyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "TestTopic";
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("Send successful: " + sendResult);
}
@Override
public void onException(Throwable e) {
System.out.println("Send failed: " + e.getMessage());
}
});
producer.shutdown();
}
}
发送单向消息
单向消息是指生产者发送消息后不需要等待Broker返回结果,适用于对消息成功发送不敏感的场景。
代码示例:
import org.apache.rocketmq.client.producer.DefaultMQProducer;
public class OneWayProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "TestTopic";
String messageBody = "Hello RocketMQ";
producer.sendOneWay(new Message(topic, messageBody.getBytes()));
producer.shutdown();
}
}
消息接收模式(集群模式与广播模式)
- 集群模式:消费者组内的消费者实例共同消费同一份消息,每个消息只会被消费一次。
- 广播模式:消费者组内的每个消费者实例都会接收到消息的全部副本。
代码示例:
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
public class ClusterConsumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.setConsumeMode(ConsumeMode.CONSUME_MINIMAL_MODE);
consumer.subscribe("TestTopic", "*");
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
System.out.println(new String(msg.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
RocketMQ常见问题与解决方法
常见错误代码解析
RocketMQ的错误代码分为以下几种类型:
- 0:成功。
- 1:网络问题。
- 2:编码问题。
- 3:参数错误。
- 4:资源不存在。
- 5:权限问题。
- 6:主题不存在。
- 7:队列不存在。
- 8:消息不存在。
- 9:消息重复。
- 10:消息过期。
- 11:消息体为空。
- 12:消息太大。
- 13:消息传输超时。
- 14:消息发送失败。
- 15:消息接收失败。
- 16:消息过滤失败。
- 17:消息路由失败。
- 18:消息存储失败。
- 19:消息读取失败。
- 20:消息删除失败。
- 21:消息查询失败。
- 22:消息轨迹查询失败。
- 23:消息轨迹不存在。
- 24:消息轨迹重复。
- 25:消息轨迹过期。
- 26:消息轨迹为空。
- 27:消息轨迹太大。
- 28:消息轨迹传输超时。
- 29:消息轨迹存储失败。
- 30:消息轨迹读取失败。
- 31:消息轨迹删除失败。
- 32:消息轨迹查询失败。
- 33:消息轨迹不存在。
- 34:消息轨迹重复。
- 35:消息轨迹过期。
- 36:消息轨迹为空。
- 37:消息轨迹太大。
- 38:消息轨迹传输超时。
- 39:消息轨迹存储失败。
- 40:消息轨迹读取失败。
- 41:消息轨迹删除失败。
- 42:消息轨迹查询失败。
- 43:消息轨迹不存在。
- 44:消息轨迹重复。
- 45:消息轨迹过期。
- 46:消息轨迹为空。
- 47:消息轨迹太大。
- 48:消息轨迹传输超时。
- 49:消息轨迹存储失败。
- 50:消息轨迹读取失败。
- 51:消息轨迹删除失败。
- 52:消息轨迹查询失败。
- 53:消息轨迹不存在。
- 54:消息轨迹重复。
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 合理设置线程池大小:根据实际业务负载调整生产者和消费者线程池的大小。
- 批量发送消息:使用批量发送消息可以降低网络传输的开销。
- 使用本地缓存:生产者可以将消息缓存在本地,减少与Broker的通信次数。
- 调整消息存储策略:根据业务需求调整消息在Broker中的存储策略,例如消息的过期时间。
- 监控和调优:使用RocketMQ提供的监控工具,监控消息队列的状态,及时发现和解决性能瓶颈。
代码示例
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
public class Producer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "TestTopic";
String messageBody = "Hello RocketMQ";
Message message = new Message(topic, messageBody.getBytes());
for (int i = 0; i < 1000; i++) {
producer.send(message);
}
producer.shutdown();
}
}
import org.apache.rocketmq.client.producer.DefaultMQProducer;
public class BatchProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("BatchProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "BatchTestTopic";
for (int i = 0; i < 1000; i++) {
String messageBody = "Batch Message " + i;
producer.send(new Message(topic, messageBody.getBytes()));
}
producer.shutdown();
}
}
消息丢失与重复问题解析
- 消息丢失:消息发送到Broker后,由于网络、Broker故障等原因可能导致消息丢失。
- 消息重复:消费者从Broker接收消息后,由于网络、消费者故障等原因可能导致消息重复。
解决方法
- 消息重试:生产者可以设置消息发送重试次数,确保消息最终发送成功。
- 消息幂等消费:消费者可以设置幂等消费机制,确保消息只被消费一次。
- 消息轨迹:使用消息轨迹功能,追踪消息的发送和接收过程,及时发现和解决消息丢失和重复问题。
代码示例
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
public class RetryProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("RetryProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.setRetryTimesWhenSendFailed(3);
producer.start();
String topic = "RetryTopic";
String messageBody = "Retry Message";
Message message = new Message(topic, messageBody.getBytes());
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("Send successful: " + sendResult);
}
@Override
public void onException(Throwable e) {
System.out.println("Send failed: " + e.getMessage());
}
});
producer.shutdown();
}
}
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.message.MessageExt;
public class IdempotentConsumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("IdempotentConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("IdempotentTopic", "*");
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
String messageBody = new String(msg.getBody());
System.out.println("Received message: " + messageBody);
// Process message
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
消费者消息堆积与处理
- 消息堆积:当消费者处理消息的速度跟不上生产者发送消息的速度时,可能会导致消息堆积。
- 消息堆积处理:可以通过增加消费者实例数、优化消息消费逻辑等方式处理消息堆积问题。
代码示例
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
public class Consumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TestTopic", "*");
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
System.out.println(new String(msg.getBody()));
try {
Thread.sleep(1000); // 模拟消息处理时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
RocketMQ实战案例
实战案例概述
本节以一个简单的电商交易系统为例,演示如何使用RocketMQ实现订单消息的异步发送和接收。系统包括订单服务和支付服务,订单服务负责生成订单并发送订单消息,支付服务负责接收订单消息并处理支付逻辑。
案例实现步骤步骤1:创建订单服务
订单服务包括订单生成、订单消息发送等逻辑。
代码示例:
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;
public class OrderService {
public void generateOrder(String orderId, String userId) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("OrderProducerGroup");
producer.setNamesrvAddr("localhost:9876");
producer.start();
String topic = "OrderTopic";
String messageBody = "OrderID: " + orderId + " UserID: " + userId;
Message message = new Message(topic, messageBody.getBytes());
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("Order message sent successfully: " + sendResult);
}
@Override
public void onException(Throwable e) {
System.out.println("Order message sent failed: " + e.getMessage());
}
});
producer.shutdown();
}
}
步骤2:创建支付服务
支付服务包括支付逻辑和订单消息接收等逻辑。
代码示例:
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
public class PaymentService {
public void processOrder(String orderId, String userId) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("PaymentConsumerGroup");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("OrderTopic", "*");
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
String messageBody = new String(msg.getBody());
System.out.println("Received order message: " + messageBody);
// Process payment logic
System.out.println("Payment processed for order: " + orderId);
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
步骤3:启动订单服务和支付服务
启动订单服务和支付服务,模拟订单生成和支付处理过程。
代码示例:
public class Main {
public static void main(String[] args) throws Exception {
OrderService orderService = new OrderService();
orderService.generateOrder("12345", "67890");
PaymentService paymentService = new PaymentService();
paymentService.processOrder("12345", "67890");
}
}
步骤4:运行案例
运行案例,模拟订单生成和支付处理过程,验证订单消息的异步发送和接收。
案例代码解析订单服务代码解析
订单服务代码中,创建了生产者实例,设置了生产者属性,发送订单消息并设置消息发送回调函数。
支付服务代码解析
支付服务代码中,创建了消费者实例,设置了消费者属性,订阅指定的主题,接收并处理订单消息。
案例总结与经验分享通过本案例,我们学习了如何使用RocketMQ实现订单消息的异步发送和接收。通过订单服务和支付服务的配合,实现了订单生成和支付处理的异步通信。实际应用中可以根据业务需求扩展更多的服务和逻辑,进一步提高系统的可靠性和性能。
通过案例实践,我们可以更好地掌握RocketMQ的核心概念和使用方法,为实际开发中的问题解决提供参考。在实际开发过程中,可以根据业务需求选择合适的消息模型、消费模式和消息处理策略,提高系统的可靠性和性能。