在分布式系统中,消息中间件是必不可少的组件之一。Apache RocketMQ 作为一款高性能的分布式消息中间件,能够支持多种消息模式,包括同步、异步、单向以及延迟消息发送。本文将通过 Java 实例代码详细讲解 RocketMQ 的这些消息发送模式,帮助你快速上手 RocketMQ 的基础功能。
一、引言
Apache RocketMQ 是阿里巴巴开源的分布式消息中间件,具备高吞吐量、低延迟和高可用性,广泛应用于消息队列、事件驱动和流式处理等场景。其多种消息模式能够适应不同业务需求,如实时通知、订单处理、异步通信等。本文将逐一介绍以下四种消息发送模式:
- 同步消息
- 异步消息
- 单向消息
- 延迟消息
二、前提条件
在开始之前,请确保已经完成以下准备工作:
- 安装并启动 RocketMQ 服务器(包括 NameServer 和 Broker)。
- 客户端能够连接到 RocketMQ 服务器,并且防火墙规则允许相应端口通信(例如:9876 端口)。
接下来,我们创建一个常量类 MqConstant
,用于存储 RocketMQ 的 NameServer 地址。在实际应用中,你可以替换成自己服务器或虚拟机的 IP 地址。
package com.takumilove.constant;
public class MqConstant {
public static final String NAME_SRV_ADDR = "localhost:9876";
}
三、消息模式实现
1. 同步消息
定义: 生产者在发送消息时会等待服务器返回发送结果后,再继续进行其他操作。
适用场景: 适用于对消息发送结果有强一致性要求的场景,如重要通知、订单状态更新等。
代码实现:
package com.takumilove.demo;
import com.takumilove.constant.MqConstant;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.junit.Test;
public class ASimpleTest {
@Test
public void simpleProducer() throws Exception {
// 1. 创建生产者实例并指定组名
DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");
// 2. 设置 NameServer 地址
producer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
// 3. 启动生产者
producer.start();
// 4. 发送消息
for (int i = 0; i < 10; i++) {
Message message = new Message("testTopic", "同步消息".getBytes());
SendResult sendResult = producer.send(message);
System.out.println(sendResult.getSendStatus());
}
// 5. 关闭生产者
producer.shutdown();
}
}
说明:
- 创建
DefaultMQProducer
实例,并指定生产者组名。 - 设置 NameServer 地址,以便生产者能够找到 Broker。
- 启动生产者,并使用
send()
方法发送消息。 - 等待服务器返回发送结果,并打印结果状态。
- 关闭生产者。
2. 异步消息
定义: 生产者发送消息后立即返回,通过回调函数处理消息发送结果,而不是等待服务器响应。
适用场景: 适合对响应时间有较高要求的场景,如视频处理、日志采集等。
代码实现:
package com.takumilove.demo;
import com.takumilove.constant.MqConstant;
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.junit.Test;
public class BASyncTest {
@Test
public void asyncProducer() throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("async-producer-group");
producer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
producer.start();
Message message = new Message("asyncTopic", "异步消息".getBytes());
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功");
}
@Override
public void onException(Throwable throwable) {
System.out.println("发送失败:" + throwable.getMessage());
}
});
System.out.println("我先执行");
System.in.read(); // 防止程序结束
}
}
说明:
- 创建
DefaultMQProducer
实例,并设置生产者组名和 NameServer 地址。 - 启动生产者,并使用
send()
方法发送异步消息,传入SendCallback
处理回调。 - 使用回调函数
onSuccess()
和onException()
分别处理发送成功和失败的情况。 - 异步消息发送后,程序继续执行其他操作而不等待结果。
3. 单向消息
定义: 生产者只负责发送消息,不等待返回结果,也没有回调函数。常用于只需要发消息而不关心其处理结果的场景。
适用场景: 日志记录、统计数据上报等。
代码实现:
package com.takumilove.demo;
import com.takumilove.constant.MqConstant;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.junit.Test;
public class COneWayTest {
@Test
public void oneWayProducer() throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("oneway-producer-group");
producer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
producer.start();
Message message = new Message("onewayTopic", "单向消息".getBytes());
producer.sendOneway(message);
System.out.println("消息已发送");
producer.shutdown();
}
}
说明:
- 使用
sendOneway()
方法发送单向消息。 - 发送后立即返回,不等待结果。
4. 延迟消息
定义: 生产者发送消息后,消息并不会立即被消费,而是在设定的时间之后才会被消费。
适用场景: 定时任务、订单超时取消、延迟通知等。
代码实现:
package com.takumilove.demo;
import com.takumilove.constant.MqConstant;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.junit.Test;
import java.util.Date;
public class DMsTest {
@Test
public void msProducer() throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("ms-producer-group");
producer.setNamesrvAddr(MqConstant.NAME_SRV_ADDR);
producer.start();
Message message = new Message("orderMsTopic", "延迟消息".getBytes());
message.setDelayTimeLevel(3); // 设置延迟级别
producer.send(message);
System.out.println("发送时间:" + new Date());
producer.shutdown();
}
}
说明:
- 使用
setDelayTimeLevel()
方法设置消息的延迟级别(1-18 对应不同延迟时间,如:1s、5s、10s 等)。 - 发送后消息将在设定的时间后被消费。
四、总结
通过本文,我们学习了 RocketMQ 中不同消息模式的基本用法,并通过代码实例演示了如何实现同步、异步、单向和延迟消息的发送。希望这些内容能够帮助你快速上手 RocketMQ,并在实际项目中灵活应用这些消息模式。