RocketMQ 基础学习

RocketMQ 基础学习

一、RocketMQ

Apache RocketMQ 是阿里巴巴研发并捐赠给 Apache 基金会的开源分布式消息中间件,定位为云原生、金融级消息引擎,核心特性为高吞吐、低延迟、高可用、强一致性,是分布式系统异步通信的核心组件。

核心应用场景:

  • 异步解耦:拆分核心链路(如订单下单 → 库存扣减 → 物流创建 → 消息通知)
  • 流量削峰:承接秒杀、大促等突发流量(如秒杀请求先入队列,消费端匀速处理)
  • 日志收集:分布式日志汇聚(如 ELK 架构中作为日志传输通道)
  • 分布式事务:基于事务消息实现最终一致性(如支付结果同步至会员系统)
  • 实时计算:对接 Flink/Spark 实现流处理(如实时订单统计)
  • 系统解耦:微服务间无侵入通信(替代 RPC 直连)

核心通信模型:

  • 发布/订阅(Pub/Sub):主流模式,基于 Topic 实现一对多通信
  • 点对点(P2P):基于 Consumer Group 负载均衡实现一对一消费

二、核心组件

组件 核心说明 关键补充
Producer(生产者) 发送消息到 Broker,支持同步、异步、单向发送 1. 支持本地事务表 + 事务消息 2. 可配置重试次数(默认 3 次) 3. 批量发送需保证单批 < 4MB
Consumer(消费者) 从 Broker 拉取/接收消息,支持集群/广播模式 1. 推模式基于长轮询(默认 30s 超时) 2. 拉模式需手动管理 Offset 3. 消费线程数可配置(默认 20)
Topic 消息的逻辑分类,类似"消息频道" 1. 一个 Topic 对应多个 MessageQueue(默认 4 个) 2. 建议按业务域划分(如 order_topic、pay_topic) 3. 支持动态扩容队列数
Broker 消息存储与转发核心节点 1. 存储结构:CommitLog(统一存储)+ ConsumeQueue(索引) 2. 主从架构:Master 写 + Slave 读 3. Dledger 模式实现自动主从切换 4. 默认保留消息 72 小时,可配置
NameServer 轻量级注册中心,管理 Broker 路由 1. 无状态,节点间不通信 2. 客户端每 30s 拉取一次路由信息 3. 集群部署需保证至少 2 个节点
Namespace 多租户/多环境隔离(阿里云商业版特性) 1. 开源版可通过 Topic 前缀模拟(如 dev_order_topic) 2. 隔离范围:Topic、Group、配置 3. 避免不同环境 Topic 命名冲突
MessageQueue Topic 的物理分区 1. 队列数决定并发消费能力 2. 集群消费时,队列均匀分配给 Consumer 实例 3. 顺序消息需保证同业务键入同队列
Offset 消费进度标识 1. 集群消费:Offset 存储在 Broker 2. 广播消费:Offset 存储在本地 3. 支持重置 Offset(按时间/位置)

架构核心特点:

  1. NameServer 无状态 → 易扩容
  2. Broker 主从/Dledger → 高可用
  3. Producer/Consumer 动态发现 Broker → 无单点
  4. 消息顺序写入 CommitLog → 高性能

三、生产者组(Producer Group)与消费者组(Consumer Group)

1. Producer Group(生产者组)

  • 定义:逻辑上相同的 Producer 实例集合(如订单服务的多个生产者节点)
  • 核心作用
    • 事务消息回查:Broker 回查未确认的事务消息时,会向该 Group 内任意在线实例发起回调
    • 运维管控:日志追踪、权限管理、监控指标聚合
  • 最佳实践
    • 事务消息必须指定唯一 Producer Group
    • 不同业务系统使用不同 Group(如 order-producer、pay-producer)
    • 非事务场景可复用,但不建议(便于问题定位)

2. Consumer Group(消费者组)

  • 定义:协同消费同一 Topic 的 Consumer 实例集合

  • 核心作用

    • 负载均衡:MessageQueue 自动分配给组内实例(队列数 ≥ 实例数最佳)
    • 高可用:实例宕机后,其负责的队列由其他实例接管
    • 独立进度:每个 Group 维护自己的 Offset,互不干扰
  • 消费模式对比(增强版)

    模式 核心逻辑 适用场景 注意事项
    集群模式(CLUSTERING) 每条消息仅被组内一个实例消费 绝大多数业务(订单、支付、通知) 实例数 ≤ 队列数,否则部分实例空闲
    广播模式(BROADCASTING) 每条消息被组内所有实例消费 配置推送、全量数据同步 无重试机制,需自行保证幂等

黄金原则:

  1. 一个业务逻辑 = 一个 Consumer Group
  2. 同一 Group 内的 Consumer 必须订阅相同的 Topic/Tag
  3. 不同业务订阅同一 Topic 必须用不同 Group

四、消费模式:推(Push) vs 拉(Pull)

RocketMQ 的"推模式"是伪推真拉(基于长轮询),框架封装了拉取逻辑;拉模式需手动控制全流程。

特性 推模式(DefaultMQPushConsumer) 拉模式(LitePullConsumer)
核心API DefaultMQPushConsumer LitePullConsumer(5.x 推荐)
消息获取 框架自动长轮询拉取,回调监听器 应用主动调用 poll() 拉取
Offset 管理 自动提交(默认 5s)/手动提交 强制手动提交(commitSync()
队列分配 自动 Rebalance(默认 20s 检测) 手动 assign()/自动 subscribe()
流控能力 内置参数控制(如 pullThresholdForQueue 完全由应用控制(可自定义限流)
并发控制 配置消费线程数(consumeThreadMin 手动控制线程池
适用场景 通用业务、快速开发、大部分场景 批处理、精准限流、流计算集成
开发成本 低(框架封装) 中高(需处理异常/重试)
资源占用 适中 灵活(可按需拉取)

推模式示例

java 复制代码
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

import java.nio.charset.StandardCharsets;

public class PushConsumerExample {
    public static void main(String[] args) throws MQClientException {
        // 1. 创建消费者实例,指定Group
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("order-consumer-group");
        
        // 2. 配置NameServer地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        
        // 3. 配置消费起始位置(首次启动从最新位置开始)
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        
        // 4. 配置消费线程数
        consumer.setConsumeThreadMin(10);
        consumer.setConsumeThreadMax(20);
        
        // 5. 订阅Topic,Tag过滤(* 表示所有Tag)
        consumer.subscribe("order_topic", "create_order || pay_success");
        
        // 6. 注册消息监听器(核心消费逻辑)
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            try {
                for (MessageExt msg : msgs) {
                    // 处理消息(示例:打印消息内容)
                    String msgBody = new String(msg.getBody(), StandardCharsets.UTF_8);
                    System.out.printf("消费消息:Topic=%s, Tag=%s, Key=%s, Body=%s%n",
                            msg.getTopic(), msg.getTags(), msg.getKeys(), msgBody);
                    
                    // 模拟业务处理
                    handleBusiness(msg);
                }
                // 消费成功
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            } catch (Exception e) {
                // 消费失败,触发重试(默认最多 16 次)
                System.err.println("消费失败,触发重试:" + e.getMessage());
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
        });
        
        // 7. 启动消费者
        consumer.start();
        System.out.println("推模式消费者启动成功");
        
        // 8. 优雅关闭(JVM 退出时)
        Runtime.getRuntime().addShutdownHook(new Thread(consumer::shutdown));
    }
    
    // 业务处理逻辑
    private static void handleBusiness(MessageExt msg) throws Exception {
        // 幂等处理(根据 msg.getKeys() 做唯一键校验)
        String uniqueKey = msg.getKeys();
        if (checkDuplicate(uniqueKey)) {
            System.out.println("消息已处理,跳过:" + uniqueKey);
            return;
        }
        // 实际业务逻辑...
    }
    
    // 幂等校验(示例)
    private static boolean checkDuplicate(String uniqueKey) {
        // 可基于Redis/数据库实现
        return false;
    }
}

拉模式示例

java 复制代码
import org.apache.rocketmq.client.consumer.LitePullConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class PullConsumerExample {
    public static void main(String[] args) throws MQClientException {
        // 1. 创建拉模式消费者
        LitePullConsumer consumer = LitePullConsumer.createPullConsumer("batch-consumer-group");
        
        // 2. 配置参数
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.setPullBatchSize(32); // 每次拉取32条
        
        // 3. 订阅Topic
        consumer.subscribe("order_topic", "*");
        
        // 4. 启动消费者
        consumer.start();
        System.out.println("拉模式消费者启动成功");
        
        // 5. 循环拉取消息
        try {
            while (!Thread.currentThread().isInterrupted()) {
                // 拉取消息(超时时间 1000ms)
                List<MessageExt> msgs = consumer.poll(1000);
                if (!msgs.isEmpty()) {
                    // 批量处理消息
                    for (MessageExt msg : msgs) {
                        String body = new String(msg.getBody(), StandardCharsets.UTF_8);
                        System.out.printf("拉取消息:Key=%s, Body=%s%n", msg.getKeys(), body);
                    }
                    // 手动提交Offset(确保消息处理完成后提交)
                    consumer.commitSync();
                    System.out.println("批量消费完成,已提交Offset");
                }
            }
        } finally {
            // 优雅关闭
            consumer.shutdown();
        }
    }
}

生产建议:

  1. 90% 场景优先使用推模式(开发效率高)
  2. 批处理/流计算场景使用拉模式
  3. 推模式建议开启手动提交 Offset(避免消息丢失)

五、消息类型详解

1. 普通消息(Normal Message)

最基础类型,无特殊语义,适用于大部分非核心场景。

java 复制代码
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class NormalMessageProducer {
    public static void main(String[] args) throws Exception {
        // 1. 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("normal-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        // 设置重试次数
        producer.setRetryTimesWhenSendFailed(3);
        
        // 2. 启动生产者
        producer.start();
        
        // 3. 构建消息(Topic, Tag, Key, Body)
        Message msg = new Message(
            "normal_topic",       // Topic
            "common_tag",         // Tag
            "ORDER_10086",        // Key(用于消息追踪/去重)
            "普通消息内容".getBytes(StandardCharsets.UTF_8)
        );
        
        // 4. 同步发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("发送成功:MsgId=%s, QueueId=%d%n", 
                sendResult.getMsgId(), sendResult.getMessageQueue().getQueueId());
        
        // 5. 关闭生产者
        producer.shutdown();
    }
}

2. 顺序消息(Ordered Message)

保证同一业务键(如订单ID)的消息按生产顺序消费,核心是"同Key入同队列 + 单线程消费"。

java 复制代码
// 生产者
public class OrderedProducer {
    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("order-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        
        // 模拟订单流程:创建→支付→发货(需保证顺序)
        String[] orderSteps = {"create", "pay", "ship"};
        String orderId = "ORDER_1001";
        
        for (String step : orderSteps) {
            Message msg = new Message(
                "order_topic",
                "order_step",
                orderId,
                String.format("订单%s:%s", orderId, step).getBytes()
            );
            
            // 按订单ID哈希选择队列(保证同订单入同队列)
            SendResult result = producer.send(msg, (mqs, msg1, arg) -> {
                String oid = (String) arg;
                int index = Math.abs(oid.hashCode()) % mqs.size();
                return mqs.get(index);
            }, orderId);
            
            System.out.printf("发送顺序消息:%s, QueueId=%d%n", step, result.getMessageQueue().getQueueId());
        }
        
        producer.shutdown();
    }
}

// 消费者(必须用 MessageListenerOrderly)
public class OrderedConsumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("order-consumer-group");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.subscribe("order_topic", "order_step");
        
        // 顺序消费监听器(单线程处理队列消息)
        consumer.registerMessageListener((msgs, context) -> {
            MessageExt msg = msgs.get(0);
            String body = new String(msg.getBody(), StandardCharsets.UTF_8);
            System.out.printf("顺序消费:QueueId=%d, Content=%s%n", 
                    msg.getQueueId(), body);
            
            // 手动提交Offset(顺序消费建议手动提交)
            context.setAutoCommit(false);
            return ConsumeOrderlyStatus.SUCCESS;
        });
        
        consumer.start();
        System.out.println("顺序消费者启动成功");
    }
}

顺序消息注意事项:

  1. 队列数决定并发度(队列越多,并发越高)
  2. 消费失败会阻塞整个队列,需快速失败或跳过
  3. 不建议用于高并发场景

3. 延迟消息(Delay Message)

延迟固定时间后投递,仅支持 18 个固定等级(开源版无自定义延迟)。

java 复制代码
public class DelayMessageProducer {
    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("delay-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        
        Message msg = new Message(
            "delay_topic",
            "delay_tag",
            "ORDER_10086",
            "订单15分钟未支付,自动取消".getBytes()
        );
        
        // 设置延迟等级(3=10秒,详见附录)
        msg.setDelayTimeLevel(5); // 等级5=1分钟
        
        SendResult result = producer.send(msg);
        System.out.println("延迟消息发送成功:" + result.getMsgId());
        
        producer.shutdown();
    }
}

4. 事务消息(Transactional Message)

实现"本地事务 + 消息发送"的最终一致性,核心流程:半消息 → 本地事务 → 提交/回滚。

java 复制代码
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;

public class TransactionProducer {
    public static void main(String[] args) throws Exception {
        // 1. 创建事务生产者
        TransactionMQProducer producer = new TransactionMQProducer("tx-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        
        // 2. 设置事务监听器
        producer.setTransactionListener(new TransactionListener() {
            // 执行本地事务
            @Override
            public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
                String orderId = msg.getKeys();
                try {
                    // 执行本地事务(如扣减库存、创建订单)
                    boolean success = executeLocalDBTransaction(orderId);
                    return success ? LocalTransactionState.COMMIT_MESSAGE 
                                   : LocalTransactionState.ROLLBACK_MESSAGE;
                } catch (Exception e) {
                    // 未知状态,等待回查
                    return LocalTransactionState.UNKNOW;
                }
            }
            
            // 事务回查(Broker主动调用)
            @Override
            public LocalTransactionState checkLocalTransaction(MessageExt msg) {
                String orderId = msg.getKeys();
                // 查询本地事务状态
                boolean isSuccess = queryLocalTransactionStatus(orderId);
                return isSuccess ? LocalTransactionState.COMMIT_MESSAGE 
                               : LocalTransactionState.ROLLBACK_MESSAGE;
            }
        });
        
        producer.start();
        
        // 3. 发送事务消息
        Message msg = new Message(
            "tx_topic",
            "tx_tag",
            "ORDER_10086",
            "订单支付事务消息".getBytes()
        );
        producer.sendMessageInTransaction(msg, null);
        
        // 4. 优雅关闭
        // producer.shutdown();
    }
    
    // 模拟本地事务执行
    private boolean executeLocalDBTransaction(String orderId) {
        // 实际业务逻辑...
        return true;
    }
    
    // 模拟查询本地事务状态
    private boolean queryLocalTransactionStatus(String orderId) {
        // 实际查询数据库...
        return true;
    }
}

5. 批量消息(Batch Message)

一次发送多条消息,提升吞吐,需满足:同Topic、同Tag、无延迟/事务、单批 < 4MB。

java 复制代码
public class BatchProducer {
    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("batch-producer-group");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        
        // 构建批量消息
        List<Message> msgList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            msgList.add(new Message(
                "batch_topic",
                "batch_tag",
                "BATCH_" + i,
                ("批量消息" + i).getBytes()
            ));
        }
        
        // 拆分超大批量(避免超过4MB)
        ListSplitter splitter = new ListSplitter(msgList);
        while (splitter.hasNext()) {
            List<Message> subList = splitter.next();
            SendResult result = producer.send(subList);
            System.out.println("批量发送成功:" + subList.size() + "条");
        }
        
        producer.shutdown();
    }
    
    // 批量消息拆分器(处理超大批量)
    static class ListSplitter implements Iterator<List<Message>> {
        private final int SIZE_LIMIT = 1024 * 1024 * 4; // 4MB
        private final List<Message> messages;
        private int currIndex;
        
        public ListSplitter(List<Message> messages) {
            this.messages = messages;
        }
        
        @Override
        public boolean hasNext() {
            return currIndex < messages.size();
        }
        
        @Override
        public List<Message> next() {
            int nextIndex = currIndex;
            int totalSize = 0;
            for (; nextIndex < messages.size(); nextIndex++) {
                Message msg = messages.get(nextIndex);
                int size = msg.getBody().length + 20; // 消息体+固定头
                if (size > SIZE_LIMIT) {
                    throw new IllegalArgumentException("单条消息超过4MB限制");
                }
                if (totalSize + size > SIZE_LIMIT) {
                    break;
                }
                totalSize += size;
            }
            List<Message> subList = messages.subList(currIndex, nextIndex);
            currIndex = nextIndex;
            return subList;
        }
    }
}

6~9. 扩展消息类型

| 类型 | 实现方式 | 核心使用场景 | 注意事项 |
|----------|-------------------------------------------------------|---------------|---------------------------------------------------------------------------------|-----------|---------------------------------------------|
| 广播消息 | consumer.setMessageModel(MessageModel.BROADCASTING) | 配置推送、全量数据同步 | 无重试,需自行保证幂等 |
| 过滤消息 | 1. Tag过滤:`subscribe("topic", "tag1 | | tag2")<br>2. SQL过滤:subscribe("topic", MessageSelector.bySql("score > 80"))` | 按业务属性筛选消息 | SQL过滤需在Broker开启 enablePropertyFilter=true |
| 重试消息 | 消费失败自动重试,默认 16 次 | 临时异常重试(如网络抖动) | 重试间隔逐渐增加(1s→5s→30s...) |
| 死信消息 | 重试 16 次失败后进入 %DLQ%{group} | 永久处理失败的消息 | 需人工介入处理,避免消息丢失 |


六、RocketMQ 优缺点

优点

维度 核心优势 补充说明
高性能 单机 10w+ TPS,毫秒级延迟 CommitLog 顺序写,ConsumeQueue 内存索引
高可靠 消息持久化 + 主从复制 + Dledger 自动容灾 支持同步/异步刷盘,满足金融级可靠性
功能丰富 原生支持顺序、事务、延迟、批量消息 相比 Kafka 功能更贴合业务场景
灵活消费 集群/广播、推/拉、Tag/SQL 过滤 Offset 可灵活重置(按时间/位置)
运维友好 支持消息轨迹、死信队列、监控指标 开源版 Dashboard 可可视化管理
生态完善 原生支持 Spring Boot/Spring Cloud 对接 Flink/Spark 实现流计算
云原生 5.x 版本支持 Proxy 架构 + gRPC 更适配 Kubernetes 容器化部署

缺点

问题 影响范围 解决方案
延迟不灵活 开源版仅支持 18 个固定等级 1. 商业版支持自定义延迟 2. 开源版可结合定时任务模拟
资源消耗高 内存/磁盘 IO 高于 Kafka 1. 合理配置 Broker 内存 2. 定期清理过期消息
运维复杂度 需维护 NameServer + Broker 集群 1. 采用 Dledger 自动主从切换 2. 配置监控告警(堆积/失败率)
使用限制多 批量/事务消息约束多 遵循最佳实践,封装通用发送工具类
学习曲线陡 新人上手慢 先掌握核心概念,再深入底层原理
管控台体验 开源版 Dashboard 功能简单 1. 商用版阿里云 MQ 控制台 2. 第三方开源管控台(如 RocketMQ-Console-NG)

七、最佳实践

1. 命名规范(标准化)

组件 命名格式 示例
Topic {业务域}_{功能}_{环境} order_create_prod, pay_notify_test
Producer Group {业务}_{角色}_{环境}_producer order_service_prod_producer
Consumer Group {业务}_{角色}_{环境}_consumer pay_notify_prod_consumer
Key {业务标识}_{唯一ID} ORDER_10086, USER_8888

2. 核心避坑指南

  1. 幂等性必做:消费端必须基于 Key 做幂等(如 Redis 分布式锁、数据库唯一键)
  2. 消息 Key 必设:用于消息追踪、去重、事务回查
  3. 避免超大消息:单条消息建议 < 1MB,超大消息用分片 + 文件存储
  4. 合理设置队列数:Topic 队列数建议为 Consumer 实例数的 2~3 倍(保证负载均衡)
  5. 消费线程数配置:根据业务 QPS 调整,默认 20 可满足大部分场景
  6. 重试次数控制 :非核心业务可减少重试次数(如 setMaxReconsumeTimes(3)
  7. 死信队列监控:配置告警,避免死信消息堆积
  8. 事务消息回查幂等checkLocalTransaction 可能多次调用,需保证幂等

3. 监控核心指标

指标 监控阈值 说明
消息堆积量 > 10000 brokerOffset - consumerOffset > 10000
消费失败率 > 1% 失败次数/总消费次数 > 1%
发送成功率 < 99.99% 发送失败需及时告警
Broker 磁盘使用率 > 80% 避免磁盘满导致消息写入失败
NameServer 存活数 < 2 保证至少 2 个 NameServer 节点可用

八、附录

1. 延迟等级对照表(默认)

等级 延迟时间 等级 延迟时间 等级 延迟时间
1 1秒 7 3分钟 13 9分钟
2 5秒 8 4分钟 14 10分钟
3 10秒 9 5分钟 15 20分钟
4 30秒 10 6分钟 16 30分钟
5 1分钟 11 7分钟 17 1小时
6 2分钟 12 8分钟 18 2小时

2. 核心配置参数(常用)

组件 参数名 默认值 建议值 说明
Producer retryTimesWhenSendFailed 3 3~5 同步发送失败重试次数
Producer retryTimesWhenSendAsyncFailed 2 2 异步发送失败重试次数
Consumer consumeThreadMin 20 10~50 最小消费线程数
Consumer consumeThreadMax 20 50~200 最大消费线程数
Consumer maxReconsumeTimes 16 3~10 最大重试次数
Consumer consumeTimeout 15分钟 3~5分钟 消费超时时间
Broker messageStoreExpireHours 72 24~72 消息保留时长(小时)

3. 常用运维命令

bash 复制代码
# 1. 查看 Topic 信息
mqadmin topicList -n 127.0.0.1:9876
mqadmin topicStatus -n 127.0.0.1:9876 -t order_topic

# 2. 查看消费堆积
mqadmin consumerProgress -n 127.0.0.1:9876 -g order-consumer-group

# 3. 重置消费 Offset(按时间)
mqadmin resetOffsetByTime -n 127.0.0.1:9876 -t order_topic -g order-consumer-group -s "2026-03-01 00:00:00"

# 4. 查看死信队列
mqadmin queryMsgByTopic -n 127.0.0.1:9876 -t %DLQ%order-consumer-group

九、总结

核心关键点

  1. 核心架构:NameServer(路由)+ Broker(存储)+ Producer/Consumer(收发),无状态设计保证高可用;
  2. 核心特性:支持顺序、事务、延迟、批量消息,满足绝大多数业务场景;
  3. 消费模式:推模式(90%场景)简单高效,拉模式适用于批处理/精准控制;
  4. 生产准则:必须保证消费幂等、合理设置重试次数、监控消息堆积;
  5. 避坑重点:顺序消息阻塞风险、事务消息回查幂等、批量消息大小限制。

适用场景总结

  • 推荐使用:异步解耦、流量削峰、分布式事务、普通业务通知;
  • 谨慎使用:超高并发(百万 TPS)、自定义延迟、极致低延迟(微秒级);
  • 不建议使用:点对点即时通信、小数据量高频次消息(建议用 RPC)。
相关推荐
重庆穿山甲1 小时前
Java开发者的大模型入门:LangChain4j组件全攻略(二)
后端
重庆穿山甲2 小时前
Java开发者的大模型入门:LangChain4j组件全攻略(一)
后端
颜酱2 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Java水解2 小时前
Rust嵌入式开发实战——从ARM裸机编程到RTOS应用
后端·rust
AI探索者2 小时前
LangGraph 条件路由:构建支持工具调用的智能 Agent
后端
苍何2 小时前
终于,我把 Openclaw 加 Seed2.0 Skills 做 AI 漫剧搞定了
后端
苍何3 小时前
阿里出手,最强Coding Plan出炉,OpenClaw可以痛快玩了
后端
风象南3 小时前
Claude Code这个隐藏技能,让我告别PPT焦虑
人工智能·后端