RocketMQ 的消息发送方式有哪几种?
RocketMQ支持同步(高可靠)、异步(低延迟)、单向(高吞吐)三种发送方式,分别适用于支付、链路及日志场景。
RocketMQ 的 Producer(生产者)发送消息主要有三种方式:同步发送(Sync)、异步发送(Async) 和 单向发送(One-way)。
这三种方式的主要区别在于 可靠性 和 性能(吞吐量/延迟)之间的权衡。
1. 同步发送 (Synchronous Sending)
这是最常用的发送方式。生产者发出消息后,会阻塞当前线程,直到收到 Broker(消息服务器)的响应(ACK)或者超时,才继续执行后续代码。
- 特点:
- 可靠性高:只有收到 Broker 的确认才算发送成功,如果失败会抛出异常,便于处理重试机制。
- 性能:相对较低,因为需要等待网络往返(RTT)。
- 代码示例:java
SendResult sendResult = producer.send(msg); - 适用场景:
- 对数据可靠性要求非常高的场景。
- 例如:重要的通知邮件、短信通知、订单创建、支付结果等。
2. 异步发送 (Asynchronous Sending)
生产者发出消息后,不阻塞当前线程,立即返回。消息发送的结果(成功或失败)会通过回调接口(Callback) 在另一个线程中通知生产者。
- 特点:
- 并发度高:不需要等待 Broker 响应即可发送下一条,降低了发送端的延迟。
- 可靠性:较高(可以通过回调处理失败情况),但代码逻辑比同步稍微复杂一点。
- 代码示例:java
producer.send(msg, new SendCallback() { @Override public void onSuccess(SendResult sendResult) { // 发送成功处理 } @Override public void onException(Throwable e) { // 发送失败处理 } }); - 适用场景:
- 对响应时间敏感(即链路耗时要求低),且需要较高吞吐量的场景。
- 例如:复杂的链路调用中需要发送消息,但不希望消息发送阻塞主流程。
3. 单向发送 (One-way Sending)
生产者只负责把消息发送出去,完全不等待 Broker 的响应,也没有回调函数。也就是“只管发,不管由于网络原因或 Broker 问题是否真正送达”。
- 特点:
- 性能最高:吞吐量最大,延迟达到微秒级。
- 可靠性最低:如果网络抖动或 Broker 宕机,消息会丢失,且生产者无法感知。
- 代码示例:java
producer.sendOneway(msg); - 适用场景:
- 允许少量消息丢失,但对吞吐量要求极高的场景。
- 例如:日志收集(Log collection)、埋点数据上报。
总结对比表
| 发送方式 | 发送机制 | 可靠性 | 吞吐量/性能 | 复杂度 | 典型场景 |
|---|---|---|---|---|---|
| 同步 (Sync) | 请求-应答 (阻塞) | 最高 | 低 | 简单 | 支付、订单、重要通知 |
| 异步 (Async) | 请求-回调 (非阻塞) | 高 | 中高 | 中等 | 耗时敏感业务 |
| 单向 (One-way) | 只发送 (不等待) | 低 | 最高 | 简单 | 日志、埋点 |
补充说明
除了上述三种底层的发送方式,RocketMQ 从业务功能角度还支持几种特殊的消息类型,虽然它们底层也是基于同步/异步发送的,但通常会被单独讨论:
- 顺序消息 (Ordered Message):保证消息按顺序消费。
- 延时/定时消息 (Scheduled/Delay Message):消息发送后不立即消费,延迟一段时间后才投递。
- 事务消息 (Transactional Message):支持分布式事务,保证本地事务和消息发送的最终一致性。
- 批量消息 (Batch Message):将多条消息合并成一个请求发送,提高吞吐量。
右滑查看面试常问