RocketMQ
文章目录
- RocketMQ
-
- RocketMQ简介
- [RabbitMQ、Kafka、RocketMQ 三大消息队列对比](#RabbitMQ、Kafka、RocketMQ 三大消息队列对比)
- 安装RocketMQ
-
- 推荐版本
- [下载Apache RocketMQ 5.3.2的源码包](#下载Apache RocketMQ 5.3.2的源码包)
- 设置环境变量
- 启动RocketMQ
- 配置可视化页面
- [SpringBoot 集成 RocketMQ](#SpringBoot 集成 RocketMQ)
RocketMQ简介
RocketMQ 作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等
官网 https://rocketmq.apache.org/
核心概念

主要由四大部分组成:
-
Producer:生产者,可以集群部署。它会先和 NameServer 集群中的随机一台建立长连接,得知当前要发送的 Topic 存在哪台 Broke Master上,然后再与其建立长连接,支持多种负载平衡模式发送消息。举例:发件人。
-
Consumer:消费者,可以集群部署。它也会先和 NameServer 集群中的随机一台建立长连接,得知当前要消息的 Topic 存在哪台 Broker Master、Slave上,然后它们建立长连接,支持集群消费和广播消费消息。举例:收件人。
-
Broker:消息队列的中间服务器,主要负责存储消息并将消息传递给消费者。支持主从部署,一个 Master 可以对应多个 Slave,Master 支持读写,Slave 只支持读。Broker 会向集群中的每一台 NameServer 注册自己的路由信息。举例:快递。
-
NameServer:是一个很简单的 Topic 路由注册中心,支持 Broker 的动态注册和发现,保存 Topic 和 Borker 之间的关系。通常也是集群部署,但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。
Topic:消息的逻辑分类,生产者发送消息到指定的Topic,消费者从指定的Topic订阅消息。一个Topic可以有多个Producer和多个Consumer。
ProducerGroup:生产者组。
ConsumerGroup:消费者组,多个消费者组可以同时消费一个主题的消息。
RabbitMQ、Kafka、RocketMQ 三大消息队列对比
| 特性 | RabbitMQ | Kafka | RocketMQ |
|---|---|---|---|
| 开发语言 | Erlang | Scala/Java | Java |
| 协议 | AMQP | 自定义协议 | 自定义协议 |
| 设计目标 | 企业级消息路由 | 高吞吐日志流 | 金融级消息队列 |
| 吞吐量 | 万级 | 十万级/百万级 | 十万级 |
| 延迟 | 微秒级 | 毫秒级 | 毫秒级 |
| 可靠性 | 高 | 非常高 | 非常高 |
| 顺序性 | 队列级别 | 分区级别 | 队列级别 |
| 事务 | 支持 | 不支持(0.11+支持) | 支持 |
| 回溯消费 | 不支持 | 支持 | 支持 |
| 消息过滤 | 简单 | 不支持 | 支持(Tag/SQL) |
| 社区生态 | 非常成熟 | 非常成熟 | 逐渐成熟 |
| 学习曲线 | 低 | 中高 | 中 |
安装RocketMQ
推荐版本
| RocketMQ 版本 | JDK 要求 | 状态 | 推荐度 |
|---|---|---|---|
| RocketMQ 5.x | JDK 17+ | 最新版 | ⭐⭐⭐⭐⭐ |
| RocketMQ 4.9.x | JDK 8-17 | 稳定版 | ⭐⭐⭐⭐ |
| RocketMQ 4.8.x | JDK 8-11 | 维护版 | ⭐⭐⭐ |
| RocketMQ 4.7.x | JDK 8 | 过时 | ⭐ |
下载Apache RocketMQ 5.3.2的源码包

设置环境变量
变量名:ROCKETMQ_HOME
变量值:MQ解压路径\MQ文件夹名(bin目录的上一级即可)

启动RocketMQ
启动NameServer
start mqnamesrv.cmd

启动Broker
start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable = true


配置可视化页面

修改rocketmq-dashboard-2.0.0-source-release\src\main\resources下边application.yml(可选)

运行Dashboard
#1. 进入 Dashboard 源码目录
cd /d D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release
# 2. 编译打包
mvn clean package -Dmaven.test.skip=true
#3. 编译成功后,jar 包在:D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release\target\
#将 application.yml 复制到 target 目录
#注意:application.yml 在 src\main\resources\ 目录下
copy src\main\resources\application.yml target\
#进入 target 目录并启动
cd /d D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release\target
#使用配置文件启动
java -jar rocketmq-dashboard-2.0.0.jar --spring.config.location=application.yml

展示了 RocketMQ Broker 和 Topic 的实时运行状态和性能指标。
**Broker TOP 10 ** 显示了消息量排名前10的Broker
Broker 5min trend
- 过去5分钟内 Broker 的消息流量趋势图
- Y轴:代表消息的生产/消费速率(TPS - 每秒事务数
主题 TOP 10 显示了消息量排名前10的 Topic
主题 5min trend
- TOPIC 在最近5分钟内的消息趋势图
- Y轴:表示该 Topic 的消息生产速率
SpringBoot 集成 RocketMQ
添加依赖
xml
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
配置文件application.yml
yml
server:
port: 8080
spring:
application:
name: rocketmq-demo
rocketmq:
# NameServer地址
name-server: 127.0.0.1:9876
producer:
group: demo-producer-group
# 发送消息超时时间,单位毫秒
send-message-timeout: 3000
# 发送失败重试次数
retry-times-when-send-failed: 2
# 异步发送失败重试次数
retry-times-when-send-async-failed: 2
# 消息最大长度
max-message-size: 4096
# 压缩消息阈值
compress-message-body-threshold: 4096
# 是否VIP通道,可避开一些检测逻辑
vip-channel-enabled: false
配置类
java
package com.hz.rocketmqtest.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RocketMQConfig {
// 可以在这里定义一些公共的Topic和Tag常量
public static final String ORDER_TOPIC = "ORDER_TOPIC";
// 订单相关的Tag
public static final String ORDER_CREATE_TAG = "ORDER_CREATE";
public static final String ORDER_PAY_TAG = "ORDER_PAY";
public static final String ORDER_CANCEL_TAG = "ORDER_CANCEL";
// 消费者组
public static final String ORDER_CONSUMER_GROUP = "ORDER_CONSUMER_GROUP";
}
实体类
java
package com.hz.rocketmqtest.pojo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class Order {
private static final long serialVersionUID = 1L;
private String orderId;
private String userId;
private BigDecimal amount;
private Integer status; // 0-待支付,1-已支付,2-已取消
private Date createTime;
private String productName;
private Integer quantity;
}
普通消息生产者
java
package com.hz.rocketmqtest.service;
import com.hz.rocketmqtest.config.RocketMQConfig;
import com.hz.rocketmqtest.pojo.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RocketMQProducer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* 发送同步消息
*/
public boolean sendSyncMessage(Order order, String tag) {
try {
// 构建消息
Message<Order> message = MessageBuilder.withPayload(order)
.setHeader("KEYS", order.getOrderId())
.build();
// 发送同步消息
org.apache.rocketmq.client.producer.SendResult sendResult =
rocketMQTemplate.syncSendOrderly(
RocketMQConfig.ORDER_TOPIC + ":" + tag,
message,
order.getOrderId()
);
log.info("同步消息发送成功,消息ID: {}, 发送状态: {}",
sendResult.getMsgId(),
sendResult.getSendStatus());
return true;
} catch (Exception e) {
log.error("同步消息发送失败", e);
return false;
}
}
/**
* 发送异步消息
*/
public void sendAsyncMessage(Order order, String tag) {
try {
Message<Order> message = MessageBuilder.withPayload(order)
.setHeader("KEYS", order.getOrderId())
.build();
rocketMQTemplate.asyncSend(
RocketMQConfig.ORDER_TOPIC + ":" + tag,
message,
new org.apache.rocketmq.client.producer.SendCallback() {
@Override
public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) {
log.info("异步消息发送成功,消息ID: {}", sendResult.getMsgId());
}
@Override
public void onException(Throwable e) {
log.error("异步消息发送失败", e);
}
}
);
} catch (Exception e) {
log.error("异步消息发送异常", e);
}
}
/**
* 发送单向消息(不关心结果)
*/
public void sendOneWayMessage(Order order, String tag) {
try {
Message<Order> message = MessageBuilder.withPayload(order)
.setHeader("KEYS", order.getOrderId())
.build();
rocketMQTemplate.sendOneWay(
RocketMQConfig.ORDER_TOPIC + ":" + tag,
message
);
log.info("单向消息发送完成");
} catch (Exception e) {
log.error("单向消息发送失败", e);
}
}
/**
* 发送延迟消息
*/
public boolean sendDelayMessage(Order order, String tag, int delayLevel) {
try {
Message<Order> message = MessageBuilder.withPayload(order)
.setHeader("KEYS", order.getOrderId())
.build();
// 延迟级别:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
org.apache.rocketmq.client.producer.SendResult sendResult =
rocketMQTemplate.syncSend(
RocketMQConfig.ORDER_TOPIC + ":" + tag,
message,
rocketMQTemplate.getProducer().getSendMsgTimeout(),
delayLevel
);
log.info("延迟消息发送成功,消息ID: {}", sendResult.getMsgId());
return true;
} catch (Exception e) {
log.error("延迟消息发送失败", e);
return false;
}
}
}
普通消息消费者
java
package com.hz.rocketmqtest.service;
import com.hz.rocketmqtest.config.RocketMQConfig;
import com.hz.rocketmqtest.pojo.Order;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.core.RocketMQListener;
@Service
@Slf4j
public class RocketMQConsumer {
/**
* 订单创建消费者
*/
@Service
@RocketMQMessageListener(
topic = RocketMQConfig.ORDER_TOPIC,
selectorExpression = RocketMQConfig.ORDER_CREATE_TAG,
consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_CREATE",
consumeMode = ConsumeMode.ORDERLY, // 顺序消费
messageModel = MessageModel.CLUSTERING // 集群模式
)
public class OrderCreateConsumer implements RocketMQListener<Order> {
@Override
public void onMessage(Order order) {
log.info("收到订单创建消息,订单ID: {}, 用户ID: {}, 金额: {}",
order.getOrderId(), order.getUserId(), order.getAmount());
// 处理订单创建逻辑
processOrderCreate(order);
}
private void processOrderCreate(Order order) {
// 实际的业务处理逻辑
log.info("处理订单创建业务...");
}
}
/**
* 订单支付消费者
*/
@Service
@RocketMQMessageListener(
topic = RocketMQConfig.ORDER_TOPIC,
selectorExpression = RocketMQConfig.ORDER_PAY_TAG,
consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_PAY",
consumeMode = ConsumeMode.CONCURRENTLY, // 并发消费
messageModel = MessageModel.CLUSTERING
)
public class OrderPayConsumer implements RocketMQListener<Order> {
@Override
public void onMessage(Order order) {
log.info("收到订单支付消息,订单ID: {}", order.getOrderId());
// 处理订单支付逻辑
processOrderPay(order);
}
private void processOrderPay(Order order) {
log.info("处理订单支付业务...");
}
}
/**
* 订单取消消费者
*/
@Service
@RocketMQMessageListener(
topic = RocketMQConfig.ORDER_TOPIC,
selectorExpression = RocketMQConfig.ORDER_CANCEL_TAG,
consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_CANCEL",
consumeMode = ConsumeMode.CONCURRENTLY,
messageModel = MessageModel.CLUSTERING
)
public class OrderCancelConsumer implements RocketMQListener<Order> {
@Override
public void onMessage(Order order) {
log.info("收到订单取消消息,订单ID: {}", order.getOrderId());
// 处理订单取消逻辑
processOrderCancel(order);
}
private void processOrderCancel(Order order) {
log.info("处理订单取消业务...");
}
}
}
Controller层
java
package com.hz.rocketmqtest.controller;
import com.hz.rocketmqtest.service.RocketMQProducer;
import com.hz.rocketmqtest.pojo.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
@RestController
@RequestMapping("/message")
@Slf4j
public class MessageController {
@Autowired
private RocketMQProducer rocketMQProducer;
/**
* 发送同步消息
*/
@PostMapping("/sendSync")
public String sendSyncMessage(@RequestParam String tag) {
Order order = createOrder();
boolean success = rocketMQProducer.sendSyncMessage(order, tag);
return success ? "同步消息发送成功" : "同步消息发送失败";
}
/**
* 发送异步消息
*/
@PostMapping("/sendAsync")
public String sendAsyncMessage(@RequestParam String tag){
Order order = createOrder();
rocketMQProducer.sendAsyncMessage(order, tag);
return "异步消息发送中...";
}
/**
* 发送单向消息
*/
@PostMapping("/sendOneWay")
public String sendOneWayMessage(@RequestParam String tag) {
Order order = createOrder();
rocketMQProducer.sendOneWayMessage(order, tag);
return "单向消息发送完成";
}
/**
* 发送延迟消息
*/
@PostMapping("/sendDelay")
public String sendDelayMessage(@RequestParam String tag,
@RequestParam(defaultValue = "3") int delayLevel) {
Order order = createOrder();
boolean success = rocketMQProducer.sendDelayMessage(order, tag, delayLevel);
return success ? "延迟消息发送成功" : "延迟消息发送失败";
}
/**
* 模拟创建订单
*/
private Order createOrder() {
Order order = new Order();
order.setOrderId(UUID.randomUUID().toString().replace("-", ""));
order.setUserId("U" + System.currentTimeMillis() % 10000);
order.setAmount(new BigDecimal("199.99"));
order.setStatus((int) (Math.random() * 3));
order.setCreateTime(new Date());
order.setProductName("测试商品");
order.setQuantity((int) (Math.random() * 10) + 1);
return order;
}
}