理解RocketMQ的消息模型

一、RocketMQ 客户端基本流程

RocketMQ 客户端分为生产者(Producer)消费者(Consumer) ,核心流程围绕 "消息生产 - 发送 - 存储 - 消费 - 确认" 展开,依赖 NameServer 进行服务发现,Broker 进行消息存储和转发。

1、生产者(Producer)核心流程

  1. 初始化与启动
    • 创建DefaultMQProducer实例,指定生产者组(Producer Group)(同类生产者的逻辑分组,用于事务消息回溯、负载均衡优化)。
    • 配置 NameServer 地址(通过setNamesrvAddr("启动服务的地址")),生产者通过 NameServer 获取 Broker 的路由信息(Topic 对应的队列分布、Broker 状态)。
    • 调用start()方法启动生产者,底层完成 Netty 客户端初始化、与 NameServer 建立连接、拉取并缓存路由信息(后续会定时更新路由)。
  2. 消息构建与发送
    • 构建Message对象,指定Topic(消息主题,消息分类标识)、Tag(消息子分类,用于消息过滤)、Key(消息唯一标识,用于查询追踪)和消息体(二进制字节数组)。
    • 调用发送方法(同步send()、异步sendAsync()、单向sendOneway()),生产者根据路由信息,通过负载均衡策略(默认轮询,支持一致性哈希等)选择对应的 Broker 和消息队列(Message Queue)。
    • 底层通过 Netty 将消息发送到 Broker,消息经过 Broker 的校验、存储后,返回发送结果(成功 / 失败、消息偏移量等)。
  3. 关闭资源 :使用完成后调用shutdown(),关闭 Netty 连接、释放缓存资源,避免内存泄漏。

2、费者(Consumer)核心流程

RocketMQ 消费者分为两种模式:推模式(PushConsumer,默认)拉模式(PullConsumer),核心流程如下:

  1. 初始化与启动
    • 创建DefaultMQPushConsumer(推模式)或DefaultMQPullConsumer(拉模式)实例,指定消费者组(Consumer Group)(同类消费者的逻辑分组,用于负载均衡、消息重试机制)。
    • 配置 NameServer 地址、订阅的 Topic(可指定 Tag,如TopicTest:TagA||TagB)。
    • 推模式需注册消息监听处理器(MessageListenerConcurrently并发消费 /MessageListenerOrderly顺序消费),拉模式需手动实现拉取逻辑。
    • 调用start()方法启动消费者,底层完成与 NameServer 建立连接、拉取路由信息、与 Broker 建立长连接、向 Broker 注册消费者组信息。
  2. 消息获取与消费
    • 推模式:Broker 主动将消息推送给消费者(底层仍是消费者定时拉取,封装为 "推" 的体验),消息到达后触发监听处理器的consumeMessage()方法执行消费业务逻辑。
    • 拉模式:消费者主动调用pull()方法,指定队列和偏移量(Offset)拉取消息,手动处理消费和偏移量提交。
  3. 关闭资源 :调用shutdown()关闭连接、释放资源,停止消息拉取 / 消费。

3、依赖关系

  • 生产者 / 消费者不直接与 Broker 耦合,通过 NameServer 获取动态路由,实现 Broker 的水平扩展。
  • 每个 Topic 对应多个 Message Queue(队列),队列是 RocketMQ 负载均衡和顺序消息的核心载体。

二、消息确认机制(ACK)

RocketMQ 的消息确认机制用于保证消息消费的可靠性,避免消息丢失或重复消费,核心分为「Broker 对生产者的 ACK」和「消费者对 Broker 的 ACK」,其中消费者 ACK 是核心重点。

1、生产者发送的 ACK(Broker 回执)

  • 同步发送:Broker 接收消息并完成持久化(写入 CommitLog)后,立即返回SendResult(包含发送状态SEND_OK、消息 ID、队列偏移量等),生产者收到 ACK 后才认为发送成功。
  • 异步发送:生产者发送消息后无需阻塞等待,Broker 处理完成后通过回调函数返回 ACK 结果。
  • 单向发送:生产者只发送消息,不接收任何 ACK 回执,适用于对可靠性要求较低的场景(如日志采集)。

2、消费者消费的 ACK(核心)

RocketMQ 消费者的 ACK 机制分并发消费顺序消费两种场景,默认采用「自动 ACK」,也支持手动 ACK,核心是通过「偏移量(Offset)」标记消费进度。

(1) 偏移量(Offset)

  • 每个 Message Queue 都有独立的 Offset,分为「存储偏移量」(Broker 中消息的物理偏移量,标记消息存储位置)和「消费偏移量」(标记消费者已消费到该队列的哪个位置)。
  • 消费者的消费进度由 Consumer Group 维护,Broker 会定期持久化 Consumer Group 的消费 Offset(默认存储在 Broker 的consumer_offset主题中)。

(2) 并发消费场景(默认)

  • 自动 ACK:消费者成功执行consumeMessage()方法(业务逻辑无异常)后,框架自动向 Broker 提交 Offset,Broker 更新该 Consumer Group 对应队列的消费进度。若消费过程中抛出异常,框架不会提交 ACK,该消息会被重新投递(进入重试队列),默认重试 16 次后进入死信队列(DLQ)。
  • 手动 ACK:通过设置consumer.setAutoCommit(false)关闭自动提交,消费成功后手动调用MessageListenerConcurrently的返回结果ConsumeConcurrentlyStatus.CONSUME_SUCCESS提交 ACK;消费失败返回RECONSUME_LATER,触发消息重试。

(3) 顺序消费场景

  • 顺序消费的 ACK 更严格,采用「阻塞式提交」:消费者消费完一条消息并返回ConsumeOrderlyStatus.SUCCESS后,才会提交该消息的 Offset,然后继续消费下一条消息。
  • 若消费失败返回SUSPEND_CURRENT_QUEUE_AWAITING,该队列会被暂停消费(默认暂停 5 秒),避免后续消息阻塞,同时该消息会被重试,保证消息的有序性不被破坏。

(4) 关键特性

  • RocketMQ 的 ACK 机制是「至少一次(At Least Once)」语义:消息不会丢失,但可能因网络抖动、消费异常导致重复消费,需要业务层实现幂等性(如基于消息 Key 去重)。
  • 不支持「恰好一次(Exactly Once)」语义,需结合业务层或分布式事务实现。

三、广播消息

1、定义

广播消息(Broadcast)是指:同一条消息会被同一个 Consumer Group 中的所有消费者实例都消费一次,而非默认的集群消费(Clustering)中消息只会被 Consumer Group 中的一个实例消费。

2、与集群消费的核心区别

特性 集群消费(默认) 广播消息
消费目标 消息被 Consumer Group 中一个实例消费 消息被 Consumer Group 中所有实例消费
消费进度维护 由 Broker 统一维护消费 Offset 每个消费者实例独立维护自己的 Offset
重试机制 支持,未消费成功的消息重试投递 不支持重试,消费失败则消息丢失
适用场景 大部分业务场景(如订单通知) 配置推送、全局通知、广播日志等

3、实现方式

只需在消费者初始化时,将消费模式设置为广播模式即可:

java 复制代码
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CONSUMER_GROUP_BROADCAST");
// 设置为广播模式(默认是集群模式:MessageModel.CLUSTERING)
consumer.setMessageModel(MessageModel.BROADCASTING);

4、注意事项

  • 广播模式下,Broker 不维护消费 Offset,每个消费者重启后会从队列的起始位置或最新位置开始消费(取决于配置),可能重复消费历史消息。
  • 不支持消息重试、死信队列,消费失败需业务层自行处理容错。
  • 广播模式下,顺序消费不生效,消息会被并发推送给所有消费者实例。

四、顺序消息机制

RocketMQ 的顺序消息是指:保证消息按照发送的顺序被消费,分为「全局顺序消息」和「分区顺序消息」,核心依赖「Message Queue 的有序性」和「消费者的顺序消费逻辑」。

1、两种顺序消息类型

(1) 全局顺序消息

  • 定义:整个 Topic 下的所有消息都按照发送顺序消费,无任何乱序。
  • 实现条件:Topic 只能创建1 个 Message Queue ,且 Consumer Group 只能有1 个消费者实例(避免负载均衡分发消息)。
  • 局限性:性能极低,无法水平扩展,仅适用于消息量极小、对全局有序要求极高的场景(如全局序列号生成)。

(2) 分区顺序消息(主流)

  • 定义:将消息按照某个关键字(如订单 ID)进行分组,同一个分组的消息发送到同一个 Message Queue,而同一个 Message Queue 的消息是有序的,从而保证「分组内有序」(局部有序)。
  • 实现核心:
    1. 生产者发送消息时,通过MessageQueueSelector自定义队列选择策略,将相同关键字的消息路由到同一个队列(如根据订单 ID 哈希取模)。
    2. 消费者使用MessageListenerOrderly(顺序消息监听器),保证对同一个队列的消息采用「单线程消费」,避免并发消费导致乱序。
  • 优势:支持水平扩展(增加 Message Queue 数量),性能优于全局顺序消息,满足大部分业务场景(如订单创建→支付→发货→完成的流程有序)。

2、实现流程(分区顺序消息)

(1) 生产者端:指定队列选择策略

java 复制代码
// 生产者发送消息时,指定订单ID作为分区关键字,相同订单ID的消息进入同一个队列
SendResult sendResult = producer.send(message, new MessageQueueSelector() {
    @Override
    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
        // arg 传入的是订单ID
        Long orderId = (Long) arg;
        // 哈希取模,保证相同订单ID路由到同一个队列
        long index = orderId % mqs.size();
        return mqs.get((int) index);
    }
}, orderId); // 传入分区关键字(订单ID)

(2) 消费者端:使用顺序消息监听器

java 复制代码
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CONSUMER_GROUP_ORDER");
// 注册顺序消息监听器(MessageListenerOrderly)
consumer.registerMessageListener(new MessageListenerOrderly() {
    @Override
    public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
        // 单线程消费同一个队列的消息,保证顺序
        MessageExt msg = msgs.get(0);
        try {
            // 执行业务消费逻辑(如订单流程处理)
            System.out.println("消费顺序消息:" + new String(msg.getBody(), StandardCharsets.UTF_8));
            // 消费成功,提交ACK,继续消费下一条
            return ConsumeOrderlyStatus.SUCCESS;
        } catch (Exception e) {
            // 消费失败,暂停当前队列消费,后续重试
            return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_AWAITING;
        }
    }
});

3、注意事项

  • 顺序消息依赖 Broker 的消息存储有序性(CommitLog 按写入顺序存储)和队列的有序分发,若 Broker 宕机切换主从,需保证主从数据同步有序(同步复制)。
  • 顺序消费时,消费者对同一个队列采用单线程处理,若某个消息消费耗时过长,会阻塞该队列后续消息的消费,需优化业务逻辑性能。
  • 顺序消息的重试机制与并发消费不同,失败后会暂停队列而非立即重试,避免乱序,重试次数可配置。

五、延迟消息

1、定义

延迟消息(Delayed Message)是指:生产者发送消息后,不希望消费者立即消费,而是等待指定的延迟时间后,才被消费者拉取和消费,RocketMQ 不支持任意时间精度的延迟,在4.x版本仅支持「固定等级的延迟」,在5.x版本已经支持"自定义时间的延迟消息",不再仅限固定等级level。

2、固定延迟等级

  • RocketMQ 默认定义了 18 个延迟等级(可通过 Broker 配置文件rocketmq-broker.conf修改),对应关系如下(核心等级):

    plaintext

    复制代码
    1: 1s, 2: 5s, 3: 10s, 4: 30s, 5: 1m,
    6: 2m, 7: 3m, 8: 4m, 9: 5m, 10: 6m,
    ... 18: 2h
  • 生产者发送消息时,只需指定延迟等级(而非具体时间),Broker 收到消息后,不会立即将其投入正常队列,而是先存储在「延迟队列」中,等待对应延迟时间到达后,再将消息转发到目标 Topic 的正常队列,供消费者消费。

3、自定义时间的延迟消息

支持按时间戳(或延迟毫秒数)投递消息,也就是不再依赖delay level,可以精确指定投递时间。

java 复制代码
消息写入 CommitLog
   ↓
记录到 TimerLog(带时间戳)
   ↓
时间轮调度
   ↓
到期后投递到真实 Topic

4、实现方式

(1)固定延迟等级

生产者构建消息时,通过setDelayTimeLevel()指定延迟等级即可:

复制代码
Message message = new Message("TOPIC_DELAY", "TAG_DELAY", "KEY_DELAY".getBytes(), "延迟消息内容".getBytes());
// 设置延迟等级为5,对应延迟1分钟
message.setDelayTimeLevel(5);
// 同步发送延迟消息
SendResult sendResult = producer.send(message);

(2)自定义延迟消息时间

java 复制代码
Message message = new Message("TopicTest", body);

// 设置绝对投递时间(时间戳)
message.setDeliveryTimestamp(System.currentTimeMillis() + 30_000);

5、对比

维度 4.x 5.x
延迟方式 delay level delivery timestamp
存储 SCHEDULE_TOPIC TimeWheel / TimerLog
调度精度 秒级 毫秒级
实现复杂度
灵活性

六、批量消息

1、定义

批量消息(Batch Message)是指:生产者将多条消息打包成一个批次,一次性发送给 Broker,而非单条发送,核心优势是减少网络通信次数、提高消息发送吞吐量。

2.、核心限制

  • 批量发送的所有消息必须属于同一个 Topic、同一个 Tag,且不能是延迟消息、事务消息。
  • 单个批量消息批次的总大小不能超过4MB(RocketMQ 默认的消息传输最大限制),若超过需进行分片处理。
  • 批量消息中的每条消息可以有独立的 Key,但队列选择策略对整个批次生效(即批次内所有消息会被路由到同一个 Message Queue)。

3、实现方式

(1) 基础批量发送(消息量小,总大小 < 4MB)

java 复制代码
// 构建多条消息,统一Topic和Tag
List<Message> messageList = new ArrayList<>();
messageList.add(new Message("TOPIC_BATCH", "TAG_BATCH", "KEY1".getBytes(), "批量消息1".getBytes()));
messageList.add(new Message("TOPIC_BATCH", "TAG_BATCH", "KEY2".getBytes(), "批量消息2".getBytes()));
messageList.add(new Message("TOPIC_BATCH", "TAG_BATCH", "KEY3".getBytes(), "批量消息3".getBytes()));

// 批量发送消息
SendResult sendResult = producer.send(messageList);

(2) 大批次消息分片(总大小 > 4MB)

当批量消息总大小超过 4MB 时,需要使用MessageBatchsplit()方法进行分片,将大批次拆分为多个小批次,逐个发送:

java 复制代码
// 构建大量消息(总大小>4MB)
List<Message> largeMessageList = new ArrayList<>();
// ... 向列表中添加大量消息

// 分片处理,每个分片不超过4MB
Iterator<List<Message>> iterator = MessageBatch.split(largeMessageList, 4 * 1024 * 1024).iterator();
while (iterator.hasNext()) {
    List<Message> subList = iterator.next();
    // 逐个发送分片批次
    SendResult sendResult = producer.send(subList);
}

4、注意事项

  • 批量消息的发送 ACK 与单条消息一致,同步发送时需等待整个批次的消息都被 Broker 持久化后,才返回整体的SendResult
  • 若批量消息中某一条消息发送失败(如格式错误),整个批次都会被 Broker 拒绝,生产者需要重新处理该批次消息。
  • 批量消息消费时,消费者会收到整个批次的消息列表,需遍历处理每条消息,ACK 机制对整个批次生效(消费成功则批量提交 Offset)。

七、过滤消息

RocketMQ 支持在「Broker 端」对消息进行过滤,只将符合条件的消息推送给消费者,减少网络传输和消费者的无效处理,分为「Tag 过滤」和「SQL92 过滤」两种核心方式。

1、Tag 过滤(推荐,高性能)

(1)特性

  • Tag 是消息的子分类,属于轻量级过滤方式,性能极高(Broker 在存储和分发时已对 Tag 进行优化,基于哈希索引)。
  • 每个消息只能设置一个 Tag,消费者订阅时可以指定单个 Tag、多个 Tag(用||分隔)或所有 Tag(用*表示)。

(2)实现方式

  • 生产者端:构建消息时指定 Tag:

    java 复制代码
    Message message = new Message("TOPIC_FILTER", "TAG_A", "KEY_FILTER".getBytes(), "TagA过滤消息".getBytes());
  • 消费者端:订阅 Topic 时指定需要的 Tag:

    java 复制代码
    // 方式1:订阅单个Tag(TAG_A)
    consumer.subscribe("TOPIC_FILTER", "TAG_A");
    
    // 方式2:订阅多个Tag(TAG_A 或 TAG_B)
    consumer.subscribe("TOPIC_FILTER", "TAG_A||TAG_B");
    
    // 方式3:订阅所有Tag
    consumer.subscribe("TOPIC_FILTER", "*");

2、SQL92 过滤(灵活,性能略低)

(1)特性

  • SQL92 过滤是基于消息的「用户属性(User Property)」进行的复杂过滤,支持ANDORNOT><=等 SQL 语法,灵活性极高

  • 性能略低于 Tag 过滤(需执行 SQL 表达式解析和匹配),默认关闭,需要在 Broker 配置文件中开启:

    XML 复制代码
    # 开启SQL92过滤支持
    enablePropertyFilter=true

(2) 实现方式

  • 生产者端:构建消息时添加用户属性(putUserProperty()):

    java 复制代码
    Message message = new Message("TOPIC_SQL_FILTER", "TAG_SQL", "KEY_SQL".getBytes(), "SQL过滤消息".getBytes());
    // 添加用户属性:订单金额、订单状态
    message.putUserProperty("orderAmount", "100");
    message.putUserProperty("orderStatus", "PAID");
  • 消费者端:使用MessageSelector.sql()指定 SQL 过滤表达式:

    java 复制代码
    // 订阅消息,过滤条件:订单金额>50 且 订单状态为PAID
    consumer.subscribe("TOPIC_SQL_FILTER", MessageSelector.sql("orderAmount > 50 AND orderStatus = 'PAID'"));

3、注意事项

  • 优先使用 Tag 过滤,仅在 Tag 无法满足需求时(如多条件组合过滤)才使用 SQL92 过滤。
  • SQL92 过滤仅支持对消息的用户属性进行操作,不支持对消息体进行过滤(消息体是二进制数据,无法解析)。
  • 消费者端的过滤条件一旦设置,后续修改需要重启消费者实例。

八、事务消息

1、定义与场景

事务消息(Transactional Message)用于解决「分布式事务」问题,保证「本地事务」和「消息发送」的原子性(要么两者都成功,要么两者都失败),适用于跨系统的数据一致性场景(如订单创建成功后,发送消息通知库存扣减)。

2、两阶段提交(2PC)+ 事务回查

RocketMQ 事务消息采用「半消息(Half Message)」+「两阶段提交」+「事务回查」的机制,保证分布式事务一致性,核心分为「生产者(事务生产者)」和「Broker(事务协调者)」两个角色。

3、核心流程

(1) 第一步:发送半消息(Half Message)

  • 事务生产者向 Broker 发送一条「半消息」,该消息被 Broker 接收并持久化,但不会被投递到目标 Topic 的队列中,消费者无法感知和消费。
  • 半消息的核心作用是 "占坑",保证消息发送的可靠性,同时标记该消息为事务待确认状态。

(2)第二步:执行本地事务

  • 生产者发送半消息成功后,执行本地业务事务(如数据库操作:创建订单)。
  • 本地事务执行完成后,生产者向 Broker 发送「事务确认请求」,包含三种状态:
    1. COMMIT_MESSAGE:本地事务执行成功,确认提交消息,Broker 将半消息转为正常消息,投递到目标 Topic,供消费者消费。
    2. ROLLBACK_MESSAGE:本地事务执行失败,确认回滚消息,Broker 删除半消息,不进行投递。
    3. UNKNOWN:本地事务执行结果未知(如网络抖动、服务宕机),Broker 会触发「事务回查」机制。

(3)第三步:Broker 事务回查(容错机制)

  • 若 Broker 长时间未收到生产者的事务确认请求,或收到UNKNOWN状态,会定期(默认 60 秒)向事务生产者发送「事务回查请求」,查询对应半消息的本地事务执行结果。
  • 生产者需要实现「事务回查接口」,根据半消息的 Key 或消息 ID,查询本地事务的最终执行状态,然后向 Broker 返回最终的确认结果(COMMIT/ROLLBACK)。
  • 事务回查有重试次数限制(默认 15 次),超过重试次数后,Broker 默认回滚消息。

4、实现方式

(1) 创建事务生产者并实现事务接口

java 复制代码
// 1. 创建事务生产者,指定生产者组
TransactionMQProducer producer = new TransactionMQProducer("PRODUCER_GROUP_TRANSACTION");
// 2. 配置NameServer地址
producer.setNamesrvAddr("127.0.0.1:9876");
// 3. 注册事务监听器(实现本地事务执行和事务回查逻辑)
producer.setTransactionListener(new TransactionListener() {
    // 实现:执行本地事务
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            // 执行本地业务事务(如:插入订单数据到数据库)
            String orderId = new String(msg.getKeys(), StandardCharsets.UTF_8);
            orderService.createOrder(orderId);
            // 本地事务成功,返回提交消息
            return LocalTransactionState.COMMIT_MESSAGE;
        } catch (Exception e) {
            // 本地事务失败,返回回滚消息
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }

    // 实现:事务回查(查询本地事务执行结果)
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        // 根据消息Key查询本地事务状态
        String orderId = new String(msg.getKeys(), StandardCharsets.UTF_8);
        Order order = orderService.getOrderById(orderId);
        if (order != null && order.getStatus() == 1) {
            // 本地事务已成功,返回提交消息
            return LocalTransactionState.COMMIT_MESSAGE;
        } else if (order == null) {
            // 本地事务未执行完成,返回未知,触发再次回查
            return LocalTransactionState.UNKNOW;
        } else {
            // 本地事务失败,返回回滚消息
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
    }
});
// 4. 启动事务生产者
producer.start();
(2) 发送事务消息
java 复制代码
Message message = new Message("TOPIC_TRANSACTION", "TAG_TRANSACTION", "ORDER_001".getBytes(), "订单创建事务消息".getBytes());
// 发送事务消息
SendResult sendResult = producer.sendMessageInTransaction(message, null);

5、注意事项

  • 事务消息仅支持同步发送,不支持异步发送和单向发送。
  • 事务消息不支持延迟消息、批量消息,也不支持 SQL92 过滤。
  • 本地事务执行逻辑需保证幂等性,避免事务回查时重复执行导致数据不一致。
  • RocketMQ 事务消息保证「最终一致性」,而非强一致性,适用于可以容忍短暂数据不一致的业务场景。

九、ACL 权限控制

1、定义与作用

ACL(Access Control List,访问控制列表)是 RocketMQ 的安全机制,用于控制客户端(生产者 / 消费者)对 Broker 的访问权限,防止未授权的客户端发送、消费或修改消息,保护 RocketMQ 集群的安全性。

2、核心功能

  • 基于「账号」的身份认证:客户端连接 Broker 时,需要提供合法的 Access Key 和 Secret Key,Broker 验证通过后才允许建立连接。
  • 基于「权限」的访问控制:对不同账号分配不同的权限,支持的核心权限包括:
    1. PUB:发送消息权限(生产者权限)。
    2. SUB:消费消息权限(消费者权限)。
    3. ALL:拥有 PUB 和 SUB 权限(管理员权限)。
    4. DENY:拒绝所有访问。
  • 支持细粒度的资源控制:可以针对具体的 Topic、Consumer Group 分配权限,实现 "某个账号仅能发送消息到 TopicA,仅能消费 TopicB"。

3、配置与启用

(1) Broker 端启用 ACL

  1. 修改 Broker 配置文件rocketmq-broker.conf,添加以下配置:

    复制代码
    # 开启ACL权限控制
    aclEnable=true
  2. 配置账号与权限:RocketMQ 默认的 ACL 配置文件为${ROCKETMQ_HOME}/conf/plain_acl.yml,核心配置内容如下:

    XML 复制代码
    # 全局配置(默认权限)
    globalWhiteRemoteAddresses:
    - 127.0.0.1 # 白名单IP,无需认证即可访问
    
    # 账号列表
    accounts:
    - accessKey: RocketMQ # 访问密钥(用户名)
      secretKey: 12345678 # 密钥(密码)
      whiteRemoteAddresses: # 该账号的白名单IP
      admin: false # 是否为管理员账号(true:拥有所有权限)
      defaultTopicPerm: SUB # 默认Topic权限
      defaultGroupPerm: SUB # 默认Group权限
      # 细粒度资源权限配置
      topicPerms:
      - TopicTest=PUB|SUB # 该账号对TopicTest拥有PUB和SUB权限
      - TopicA=PUB # 该账号对TopicA仅拥有PUB权限
      groupPerms:
      - ConsumerGroupTest=SUB # 该账号对ConsumerGroupTest仅拥有SUB权限
  3. 重启 Broker,使 ACL 配置生效。

(2)客户端配置账号信息

生产者和消费者需要配置 Access Key 和 Secret Key,才能通过 Broker 的 ACL 认证:

java 复制代码
// 生产者配置ACL
DefaultMQProducer producer = new DefaultMQProducer("PRODUCER_GROUP_ACL");
producer.setNamesrvAddr("127.0.0.1:9876");
// 配置Access Key和Secret Key
producer.setAccessKey("RocketMQ");
producer.setSecretKey("12345678");

// 消费者配置ACL
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CONSUMER_GROUP_ACL");
consumer.setNamesrvAddr("127.0.0.1:9876");
// 配置Access Key和Secret Key
consumer.setAccessKey("RocketMQ");
consumer.setSecretKey("12345678");

4、注意事项

  • ACL 机制仅对客户端与 Broker 的通信进行认证和授权,不对 NameServer 进行控制(NameServer 无状态,不存储消息)。
  • 生产环境中,应避免使用默认账号和密码,定期更换 Secret Key,提高安全性。
  • 若客户端未配置账号信息,或账号权限不足,连接 Broker 时会抛出NoPermissionException异常。
  • ACL 权限控制会带来轻微的性能损耗(认证和权限校验),但对大部分业务场景影响可忽略。
相关推荐
很搞笑的在打麻将2 小时前
Java集合线程安全实践:从ArrayList数据迁移问题到synchronizedList解决方案
java·jvm·算法
坚持学习前端日记2 小时前
微服务模块化项目结构
java·jvm·微服务
烤麻辣烫2 小时前
java进阶--刷题与详解-1
java·开发语言·学习·intellij-idea
cypking2 小时前
一、Mac 下 JDK + Maven 安装配置文档(Bash 终端 / Source 生效)
java·macos·maven
七夜zippoe2 小时前
分布式事务解决方案 Seata AT模式深度解析
java·sql·seata·at·xa·undo log
计算机毕设指导62 小时前
基于微信小程序的社区医疗服务管理系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
Java天梯之路2 小时前
Spring Boot 钩子全集实战(六):SpringApplicationRunListener.contextPrepared()详解
java·spring boot·后端
小小仙。2 小时前
IT自学第十八天
java·开发语言·算法
我命由我123452 小时前
Android 开发 - FragmentPagerAdapter、Pair、ClipboardManager、PopupWindow
android·java·java-ee·kotlin·android studio·android-studio·android runtime