RocketMQ 核心特性实战详解

🚩RocketMQ 核心特性实战详解

本文基于 RocketMQ 4.x + rocketmq-spring-boot-starter 2.3.1,从零搭建,逐步讲解 RocketMQ 11大核心特性,每一段代码都能直接跑。


0. 项目环境准备

依赖引入

pom.xml 文件添加:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.3.1</version>
</dependency>

配置文件 application.yml

server:
  port: 8080

spring:
  rocketmq:
    name-server: 127.0.0.1:9876 # RocketMQ NameServer 地址
    producer:
      group: demo-producer-group # 默认生产者组
    consumer:
      group: demo-consumer-group # 默认消费者组

本地启动 RocketMQ 可以使用 Docker,示例见文末。


1. 普通消息(Standard Message)

应用场景

  • 注册成功后,发送欢迎短信/邮件通知。

完整代码

1.1 生产者
package com.example.rocketmq.producer;

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

@Service
public class StandardMessageProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发送普通消息
     * @param topic 消息主题
     * @param message 消息内容
     */
    public void send(String topic, String message) {
        rocketMQTemplate.send(topic, MessageBuilder.withPayload(message).build());
    }
}
1.2 消费者
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 普通消息消费者
 */
@Service
@RocketMQMessageListener(topic = "register-topic", consumerGroup = "register-consumer-group")
public class StandardMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【普通消息】收到消息:" + message);
    }
}
1.3 Controller 测试入口
package com.example.rocketmq.controller;

import com.example.rocketmq.producer.StandardMessageProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/standard")
public class StandardMessageController {

    @Autowired
    private StandardMessageProducer producer;

    @PostMapping("/send")
    public String sendMessage(@RequestParam String message) {
        producer.send("register-topic", message);
        return "普通消息发送成功";
    }
}

2. 定时/延时消息(Delayed Message)

应用场景

  • 下单 30分钟未支付,自动取消订单。

完整代码

2.1 生产者
package com.example.rocketmq.producer;

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

@Service
public class DelayedMessageProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发送延时消息
     * @param topic 消息主题
     * @param message 消息内容
     * @param delayLevel 延迟等级
     */
    public void send(String topic, String message, int delayLevel) {
        rocketMQTemplate.syncSend(topic, MessageBuilder.withPayload(message).build(), 3000, delayLevel);
    }
}
2.2 消费者
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 延迟消息消费者
 */
@Service
@RocketMQMessageListener(topic = "order-cancel-topic", consumerGroup = "delay-consumer-group")
public class DelayedMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【延迟消息】收到消息:" + message);
    }
}
2.3 Controller 测试入口
package com.example.rocketmq.controller;

import com.example.rocketmq.producer.DelayedMessageProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/delay")
public class DelayedMessageController {

    @Autowired
    private DelayedMessageProducer producer;

    @PostMapping("/send")
    public String sendDelayMessage(@RequestParam String message, @RequestParam int delayLevel) {
        producer.send("order-cancel-topic", message, delayLevel);
        return "延迟消息发送成功";
    }
}

🚨注意:RocketMQ 支持固定的延迟等级,不支持任意延迟。


3. 顺序消息(Ordered Message)

应用场景

  • 订单生命周期:下单 → 支付 → 发货,顺序执行。

完整代码

3.1 生产者
package com.example.rocketmq.producer;

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderedMessageProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发送顺序消息
     * @param topic 消息主题
     * @param message 消息内容
     * @param hashKey 用于分区的 key
     */
    public void send(String topic, String message, String hashKey) {
        rocketMQTemplate.syncSendOrderly(topic, message, hashKey);
    }
}
3.2 消费者
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 顺序消息消费者
 */
@Service
@RocketMQMessageListener(topic = "order-topic", consumerGroup = "order-consumer-group")
public class OrderedMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【顺序消息】收到消息:" + message);
    }
}
3.3 Controller 测试入口
package com.example.rocketmq.controller;

import com.example.rocketmq.producer.OrderedMessageProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/order")
public class OrderedMessageController {

    @Autowired
    private OrderedMessageProducer producer;

    @PostMapping("/send")
    public String sendOrderedMessage(@RequestParam String message, @RequestParam String hashKey) {
        producer.send("order-topic", message, hashKey);
        return "顺序消息发送成功";
    }
}

4. 事务消息(Transactional Message)

应用场景

  • 分布式事务,订单保存和库存扣减一致性控制。

完整代码

4.1 生产者
package com.example.rocketmq.producer;

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.Service;

@Service
public class TransactionalMessageProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发送事务消息
     * @param topic 消息主题
     * @param message 消息内容
     */
    public void send(String topic, String message) {
        Message<String> msg = MessageBuilder.withPayload(message).build();
        rocketMQTemplate.sendMessageInTransaction(topic, msg, null);
    }
}
4.2 事务监听器
package com.example.rocketmq.listener;

import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

/**
 * 事务消息监听器
 */
@Component
@RocketMQTransactionListener(txProducerGroup = "demo-producer-group")
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        // 执行本地事务
        System.out.println("执行本地事务:" + message.getPayload());
        // 这里模拟成功提交
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        // 回查本地事务状态
        System.out.println("回查事务状态:" + message.getPayload());
        return RocketMQLocalTransactionState.COMMIT;
    }
}
4.3 Controller 测试入口
package com.example.rocketmq.controller;

import com.example.rocketmq.producer.TransactionalMessageProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/transaction")
public class TransactionalMessageController {

    @Autowired
    private TransactionalMessageProducer producer;

    @PostMapping("/send")
    public String sendTransactionalMessage(@RequestParam String message) {
        producer.send("transactional-topic", message);
        return "事务消息发送成功";
    }
}

5. 消息发送重试与流控机制

应用场景

  • 网络抖动、Broker瞬时不可用时,重试保证消息送达。
  • 高并发场景限流,保护 Broker,防止系统雪崩。

配置方式

application.yml 配置发送重试次数:

spring:
  rocketmq:
    producer:
      retry-times-when-send-failed: 5 # 默认3次,这里改为5次

6. 消费者分类(Consumer Group)

应用场景

  • 统计系统和风控系统都需要消费订单完成消息,但彼此独立。

完整代码

6.1 消费者1(统计系统)
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 统计系统消费者
 */
@Service
@RocketMQMessageListener(topic = "order-finished-topic", consumerGroup = "analytics-consumer-group")
public class AnalyticsConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【统计系统】收到订单完成消息:" + message);
    }
}
6.2 消费者2(风控系统)
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 风控系统消费者
 */
@Service
@RocketMQMessageListener(topic = "order-finished-topic", consumerGroup = "risk-control-consumer-group")
public class RiskControlConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【风控系统】收到订单完成消息:" + message);
    }
}

7. 消息过滤(Message Filter)

应用场景

  • 不同类型订单按需消费,比如只处理高价值订单。

7.1 Tag 过滤

生产者发送消息时打 Tag:

rocketMQTemplate.syncSend("filter-topic:vip", "VIP用户下单");
rocketMQTemplate.syncSend("filter-topic:normal", "普通用户下单");

消费者按 Tag 订阅:

package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * Tag过滤消费者
 */
@Service
@RocketMQMessageListener(topic = "filter-topic", consumerGroup = "vip-consumer-group", selectorExpression = "vip")
public class TagFilterConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【VIP订单】收到消息:" + message);
    }
}

🚨注意:Tag 过滤只能是单标签或者 || 组合。


8. 消费者负载均衡(Load Balance)

应用场景

  • 大促期间流量激增,水平扩展消费端。

RocketMQ 默认机制

  • 同一 Consumer Group 内,多个消费者实例自动分摊队列(Queue)。

示意:

QueueConsumer1Consumer2
Q0✔️
Q1✔️
Q2✔️
Q3✔️

👉实际代码和上面一样,只需要部署多个实例**,RocketMQ 自动分配。


9. 消费进度管理(Offset Management)

应用场景

  • 确保消息消费成功,失败时可以断点续传,不丢消息。

RocketMQ 默认

  • 自动提交 Offset,确保 At Least Once

若想手动控制(进阶用法,适合批量消费)需改用底层 API MessageListenerConcurrently


10. 消息重试(Message Retry)

应用场景

  • 消费失败,RocketMQ 自动进行重试,最大16次。

完整代码

消费者模拟失败
package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 消息重试消费者
 */
@Service
@RocketMQMessageListener(topic = "retry-topic", consumerGroup = "retry-consumer-group")
public class RetryConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【重试机制】收到消息:" + message);
        if (message.contains("fail")) {
            throw new RuntimeException("消费失败,触发重试");
        }
    }
}

RocketMQ 会根据消费失败次数进行重试,超过最大次数会进入 死信队列 DLQ


11. 消息存储和清理机制(Storage & Cleanup)

应用场景

  • 大量堆积消息时,合理清理过期消息,防止磁盘爆满。

Broker 配置(broker.conf

fileReservedTime=72 # 消息保存时间(小时)
cleanFileForciblyEnable=true # 启用强制清理

清理规则:

  • 消息保存超过 fileReservedTime 时间,会被清除。
  • 磁盘使用率超过阈值(75%),触发强制清理。

🚀完整测试方法

  1. 启动 RocketMQ 集群(见下)
  2. 启动本项目
  3. 通过 Postman、curl 调用各 Controller 接口

🐳本地 RocketMQ 快速启动 (Docker版)

新建 docker-compose.yml

version: '3.7'
services:
  namesrv:
    image: apache/rocketmq:4.9.3
    container_name: rmqnamesrv
    ports:
      - "9876:9876"
    environment:
      JAVA_OPT_EXT: "-Xms512m -Xmx512m"
    command: sh mqnamesrv

  broker:
    image: apache/rocketmq:4.9.3
    container_name: rmqbroker
    ports:
      - "10911:10911"
      - "10909:10909"
    environment:
      JAVA_OPT_EXT: "-Xms512m -Xmx512m"
      NAMESRV_ADDR: namesrv:9876
      BROKER_ID: 0
      BROKER_NAME: broker-a
      BROKER_CLUSTER_NAME: DefaultCluster
    volumes:
      - ./broker.conf:/opt/rocketmq-4.9.3/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq-4.9.3/conf/broker.conf
    depends_on:
      - namesrv

新建 broker.conf

brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
listenPort=10911

执行启动:

docker-compose up -d

🎯总结

功能特性项目应用场景
普通消息用户注册、订单通知、积分发放
定时/延时消息超时关单、定时推送
顺序消息订单流转、物流更新
事务消息下单扣库存一致性控制
消息发送重试保证网络异常时消息可靠送达
消费者分类多业务系统独立消费
消息过滤精准推送特定类型消息
消费者负载均衡消费者水平扩展
消费进度管理消费状态持久化,防止重复丢失
消息重试消费异常自动重试,保护业务处理
存储清理机制硬盘保护,防止大数据量堆积导致系统崩溃
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愤怒的代码

如果您有受益,欢迎打赏博主😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值