刚入行的 Java 开发的时候,第一次接触消息队列时我总觉得这东西高深莫测。其实上手后发现,RocketMQ 作为国产消息队列,文档全、社区活跃,特别适合新手学习。这篇指南就从环境搭建到代码编写,手把手带你搞定 RocketMQ 的基本用法。
一、先搞懂:为什么需要消息队列?
刚开始我也疑惑,直接调用接口不就行了,为啥要多此一举用 MQ?直到遇到这几个场景:
- 用户注册后要发验证码、送优惠券、加积分,同步调用经常超时
- 秒杀活动瞬间请求量太大,直接打垮数据库
- 订单系统和库存系统耦合太紧,改一点代码两边都要测试
消息队列就像个 "快递中转站":发送方把消息丢进去就完事,接收方慢慢处理,既能削峰填谷,又能解耦系统。RocketMQ 就是其中性能不错的一款。
二、环境搭建:3 步跑起 RocketMQ
2.1 下载安装(Windows 为例)
- 到RocketMQ 官网下载最新版二进制包(我用的是 4.9.4,新手建议选稳定版)
- 解压到本地目录(比如
D:\rocketmq
),路径里别带中文和空格 - 配置环境变量:新增
ROCKETMQ_HOME
,值为解压目录;在Path
里添加%ROCKETMQ_HOME%\bin
2.2 启动服务
打开两个命令提示符窗口(一定要用管理员身份!):
第一个窗口启动 NameServer:
cd D:\rocketmq\bin
start mqnamesrv.cmd
看到The Name Server boot success
就说明启动成功了
第二个窗口启动 Broker:
cd D:\rocketmq\bin
start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
出现The broker[xxx, 127.0.0.1:10911] boot success
就 OK 了(如果启动失败,可能是内存不够,后面会说解决办法)
2.3 安装控制台(可视化界面)
新手一定要装这个,不然消息发没发出去都不知道:
- 从github 下载控制台源码
- 用 IDEA 打开,修改
application.properties
:
properties
rocketmq.config.namesrvAddr=127.0.0.1:9876
- 打包:
mvn clean package -Dmaven.test.skip=true
- 运行:
java -jar target/rocketmq-dashboard-1.0.1.jar
- 访问
http://localhost:8080
,能看到控制台页面就成功了
小技巧:如果启动 Broker 时报内存不足,找到bin
目录下的runbroker.cmd
,把里面的-Xms8g -Xmx8g -Xmn4g
改小,比如改成-Xms512m -Xmx512m -Xmn256m
三、代码实战:发送和接收第一条消息
3.1 引入依赖
在 Spring Boot 项目的pom.xml
里加依赖(版本和你的 RocketMQ 保持一致):
xml
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.3</version>
</dependency>
3.2 配置 application.yml
yaml
rocketmq:
name-server: 127.0.0.1:9876 # NameServer地址
producer:
group: demo-producer-group # 生产者组,随便起个名字
3.3 发送消息(生产者)
写个简单的 Controller 测试发送:
@RestController
public class MessageController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
// 发送普通消息
@GetMapping("/send")
public String sendMessage(String content) {
// 参数1:topic(如果不存在会自动创建),参数2:消息内容
rocketMQTemplate.convertAndSend("demo-topic", content);
return "消息发送成功:" + content;
}
}
启动项目,访问http://localhost:8080/send?content=hello rocketmq
,看到返回成功就说明消息发出去了
3.4 接收消息(消费者)
写个消费者监听消息:
@Component
// topic要和发送时一致,consumerGroup自己起
@RocketMQMessageListener(topic = "demo-topic", consumerGroup = "demo-consumer-group")
public class DemoConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("收到消息:" + message);
// 这里可以写业务逻辑,比如更新数据库、调用其他接口
}
}
重启项目后,再发一条消息,控制台会打印 "收到消息:xxx",说明消费成功了
四、查看消息:控制台怎么用?
- 打开
http://localhost:8080
,在左侧菜单点主题
,能看到我们创建的demo-topic
- 点
主题名称
进去,能看到消息总数、消费情况 - 想查看具体消息内容?点
消息查询
,输入 topic,选查询所有消息
,就能看到每条消息的内容、发送时间 - 如果消息没被消费,在
消费者管理
里看看消费者组是否在线 - 重点看
堆积数
:如果这个数字一直在涨,说明消费者处理不过来,可能需要优化消费逻辑
五、进阶一点:常见场景代码
5.1 发送带标签的消息(用于消息分类)
比如订单消息分 "创建" 和 "支付":
// 发送时在topic后面加:标签
rocketMQTemplate.convertAndSend("order-topic:create", "订单123创建了");
rocketMQTemplate.convertAndSend("order-topic:pay", "订单123支付了");
消费者可以只接收特定标签的消息:
// selectorExpression指定标签,*表示所有标签
@RocketMQMessageListener(
topic = "order-topic",
consumerGroup = "order-consumer",
selectorExpression = "create" // 只消费create标签的消息
)
public class OrderConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("处理订单创建消息:" + message);
}
}
5.2 发送对象消息
实际开发中经常发送对象,比如 User:
java
// 定义User类(必须实现Serializable)
public class User implements Serializable {
private Long id;
private String name;
// getters and setters
}
// 发送对象
@GetMapping("/sendUser")
public String sendUser() {
User user = new User();
user.setId(1L);
user.setName("张三");
rocketMQTemplate.convertAndSend("user-topic", user);
return "用户消息发送成功";
}
// 接收对象
@RocketMQMessageListener(topic = "user-topic", consumerGroup = "user-consumer")
public class UserConsumer implements RocketMQListener<User> {
@Override
public void onMessage(User user) {
System.out.println("收到用户:" + user.getName());
}
}
六、踩坑记录:新手常遇到的问题
-
消息发送成功但消费不到:
- 检查消费者组是否和代码里的
consumerGroup
一致 - 看看是不是用了标签,发送和接收的标签对不上
- 重启一下消费者服务试试
- 检查消费者组是否和代码里的
-
启动 Broker 失败:
- 一定要用管理员身份启动命令提示符
- 内存不够就改
runbroker.cmd
里的配置
-
控制台连接不上 NameServer:
- 检查
application.properties
里的namesrvAddr
是否正确 - 确认 NameServer 是否在运行
- 检查
-
消息重复消费:
- RocketMQ 默认会重试,所以消费逻辑要写 "幂等性"(比如用订单号判断是否处理过)
七、总结
作为新手,掌握这些基本操作就够用了:
- 用
rocketmqTemplate.convertAndSend
发送消息 - 写个类实现
RocketMQListener
接收消息 - 通过控制台查看消息状态和消费情况
- 遇到问题先看控制台的堆积数和错误日志
RocketMQ 还有很多高级功能,比如事务消息、延时消息,等熟练了再慢慢学。刚开始不用追求面面俱到,先在实际项目中用起来,遇到问题再查文档,进步会更快~
如果有哪里没看懂,可以评论区问我,我会尽量用新手能听懂的话解答~