🚀 RocketMQ 生产者(Producer)详解
生产者(Producer)是 RocketMQ 的消息发送端,负责创建并发送消息到指定的 Topic。它是整个消息链路的起点,其性能、可靠性与使用方式直接影响系统的吞吐量、一致性和稳定性。
一、Producer 的核心职责
| 职责 | 说明 |
|---|---|
| 创建消息 | 构造 Message 对象,包含 Body、Topic、Tag、Key 等 |
| 获取路由信息 | 从 NameServer 获取 Topic 分布在哪些 Broker 上 |
| 选择 MessageQueue | 根据负载策略选择一个队列发送消息(轮询、哈希等) |
| 发送消息 | 向目标 Broker 的 Master 节点发送消息 |
| 处理响应与重试 | 接收 ACK 或异常,支持自动重试机制 |
| 事务控制(可选) | 实现事务消息,保证本地事务与消息发送的一致性 |
二、Producer 的核心接口与类型
RocketMQ 提供了多种类型的生产者,适用于不同场景:
1. DefaultMQProducer(默认生产者)
最常用的生产者,支持同步、异步、单向和事务消息。
DefaultMQProducer producer = new DefaultMQProducer("producer_group");
producer.setNamesrvAddr("192.168.0.1:9876");
producer.start();
2. TransactionMQProducer(事务生产者)
用于实现半事务消息,配合事务监听器实现“本地事务 + 消息发送”的最终一致性。
TransactionMQProducer producer = new TransactionMQProducer("tx_producer_group");
producer.setTransactionListener(new MyTransactionListener());
三、消息发送模式
| 模式 | 特点 | 适用场景 |
|---|---|---|
| ✅ 同步发送(Sync Send) | 发送后等待 Broker 返回确认,成功才继续 | 关键业务,如订单创建 |
| ✅ 异步发送(Async Send) | 不阻塞主线程,通过回调通知结果 | 高并发、高吞吐场景 |
| ✅ 单向发送(Oneway Send) | 只发不等,无回调 | 日志、监控等允许丢失的场景 |
| ✅ 事务消息(Transaction) | 先发“半消息”,执行本地事务后再提交 | 分布式事务场景 |
📌 示例代码
1. 同步发送
Message msg = new Message("TopicTest", "TagA", "Hello RocketMQ".getBytes());
SendResult result = producer.send(msg);
System.out.println("发送结果:" + result.getSendStatus());
2. 异步发送
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult result) {
System.out.println("发送成功:" + result);
}
@Override
public void onException(Throwable e) {
System.out.println("发送失败:" + e.getMessage());
}
});
3. 单向发送
producer.sendOneway(msg);
// 不关心结果,立即返回
4. 事务消息(简略)
TransactionMQProducer producer = new TransactionMQProducer("TxGroup");
producer.setTransactionListener(new TransactionListener() {
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
// 执行本地事务(如扣库存)
return LocalTransactionState.COMMIT_MESSAGE;
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
// 检查本地事务状态(Broker 回查)
return LocalTransactionState.COMMIT_MESSAGE;
}
});
四、Producer 的关键配置参数
| 参数 | 说明 | 建议值 |
|---|---|---|
producerGroup | 生产者组名,逻辑上相同角色的 Producer 归属同一组 | 自定义,如 order_producer |
namesrvAddr | NameServer 地址列表 | 192.168.0.1:9876;192.168.0.2:9876 |
sendMsgTimeout | 发送超时时间(毫秒) | 3000~5000 |
retryTimesWhenSendFailed | 同步发送失败重试次数 | 2(默认) |
retryTimesWhenSendAsyncFailed | 异步发送失败重试次数 | 2 |
compressMsgBodyOverHowmuch | 消息体超过多少字节进行压缩 | 4096(4KB) |
maxMessageSize | 最大消息大小 | 4MB(Broker 限制) |
instanceName | 实例名,用于区分同一 JVM 中多个 Producer | 可设为 IP 或端口 |
⚠️ 注意:ProducerGroup 在集群部署中必须一致,否则可能导致路由混乱。
五、Producer 的工作流程
1. 启动 Producer
↓
2. 从 NameServer 获取 Topic 路由信息(Broker + Queue 列表)
↓
3. 根据负载策略选择一个 MessageQueue
↓
4. 找到该 Queue 对应的 Master Broker 地址
↓
5. 向 Broker 发送消息(同步/异步/单向)
↓
6. 接收 ACK 或异常,处理结果(重试或回调)
🔄 路由获取机制
- Producer 启动时从任意 NameServer 拉取路由表。
- 每隔 30 秒定时更新路由信息(防止 Broker 变更导致发送失败)。
🎯 负载均衡策略(选择 Queue)
- 默认:轮询(Round Robin),均匀分布消息
- 可自定义:如按 Key 哈希,保证相同 Key 的消息进入同一 Queue(有序性)
SendResult result = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
return mqs.get(id % mqs.size());
}
}, orderId);
六、高可用与容错机制
1. 自动重试
- 同步发送失败时,默认重试 2 次(共 3 次尝试)
- 重试会尝试发送到其他 Broker(避免主节点宕机)
⚠️ 注意:重试可能导致消息重复,需消费者做幂等处理。
2. 主从切换
- Producer 只向 Master Broker 发送消息
- 若 Master 宕机,NameServer 会更新路由,Producer 下次发送将选择新的 Master
3. 连接池管理
- 内部维护 Netty 客户端连接池,复用 TCP 连接,提升性能
七、事务消息原理(重点)
RocketMQ 的事务消息用于解决“本地事务与消息发送”的一致性问题。
🔄 三阶段流程:
-
发送半消息(Half Message)
- Producer 发送一条“不可见”消息到 Broker(暂不投递给 Consumer)
-
执行本地事务
- Broker 返回成功后,Producer 执行本地操作(如扣库存、写数据库)
-
提交或回滚事务
- 成功 → 提交
COMMIT_MESSAGE - 失败 → 提交
ROLLBACK_MESSAGE - 超时未响应 → Broker 回查
checkLocalTransaction
- 成功 → 提交
🔁 回查机制
- 如果 Producer 崩溃未提交状态,Broker 会每隔一定时间(默认 30s)发起回查。
- Producer 必须实现
checkLocalTransaction方法,返回本地事务真实状态。
✅ 优势:实现“最终一致性”,避免因网络问题导致消息丢失或事务不一致。
八、最佳实践与注意事项
| 实践 | 说明 |
|---|---|
| ✅ 使用 Producer Pool | 避免频繁创建销毁 Producer,建议全局单例 |
| ✅ 设置合理的超时和重试 | 防止线程阻塞,避免雪崩 |
| ✅ 合理设置 Tag 和 Key | 便于消息过滤、排查和索引 |
| ✅ 控制消息大小 | 单条建议 ≤ 4MB,避免影响性能 |
| ✅ 开启压缩 | 大消息(>4KB)建议开启压缩 |
| ✅ 事务消息谨慎使用 | 增加复杂度,仅用于强一致性场景 |
| ✅ 监控 SendResult | 关注 SEND_OK, FLUSH_DISK_TIMEOUT 等状态 |
九、常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 发送超时 | 网络不通、Broker 压力大 | 检查网络、扩容 Broker |
NO_TOPIC_ROUTE_INFO | Topic 未创建或路由未更新 | 手动创建 Topic 或等待路由同步 |
| 消息重复 | 重试机制导致 | 消费者做幂等处理 |
| 事务消息未提交 | Producer 崩溃 | 实现回查逻辑,确保状态可查 |
✅ 总结
| 特性 | 说明 |
|---|---|
| 角色 | 消息的发起者 |
| 通信对象 | NameServer(获取路由)、Broker(发送消息) |
| 核心能力 | 同步/异步/单向/事务发送、负载均衡、重试机制 |
| 设计目标 | 高性能、高可用、高可靠 |
| 关键点 | 路由获取、Queue 选择、重试策略、事务一致性 |
🚀 一句话总结:
RocketMQ 的 Producer 不只是一个“发消息的工具”,而是一个集路由管理、负载均衡、容错重试、事务控制于一体的智能客户端,是构建可靠消息系统的起点。
掌握 Producer 的使用与原理,是深入 RocketMQ 的第一步。
1757

被折叠的 条评论
为什么被折叠?



