RocketMQ是阿里开源的一款非常优秀的中间件产品,后捐赠给Apache基金会作为一款孵化技术,仅仅经历了一年多的时间就成为Apache基金会的顶级项目。RocketMQ是一款分布式、队列模型的消息中间件,支持分布式事务,天然的支持集群模型、负载均衡、水平扩展能力,亿级别的消息堆积能力。
RocketMQ的使用场景包括:
- 异步通信:RocketMQ 可以在不同的应用程序之间进行异步通信,从而提高系统的可伸缩性和响应速度。同时减少多个模块之间的依赖性,使整个系统更加灵活并易于维护。
- 应用解耦:通过RocketMQ作为中介,生产方与消费方通过消息进行交互,减少多个模块之间的依赖性,使整个系统更加灵活并易于维护。
- 削峰填谷:RocketMQ 可以用于平滑处理流量峰值,将请求缓冲并逐渐处理,以防止系统过载。例如,在大型活动(如秒杀、抢红包、企业开门红等)中,通过RocketMQ的削峰填谷能力,平稳流量峰值,避免系统压力过大。
- 保证消息顺序:适用于需要保证多条消息处理顺序的场景,例如证券交易过程、订单创建、支付、退款等流程。
- 事件驱动架构:RocketMQ 适用于构建事件驱动的架构,以便快速响应事件和状态变化。
- 日志收集:统一收集业务日志,供分析系统进行数据分析,消息队列作为日志数据的中转站。并且,RocketMQ 的流式计算框架非常适合与大数据框架集成,如 Apache Hadoop 和 Flink 等,用于构建实时数据流处理。
总之,RocketMQ是一个功能强大的消息中间件,适用于各种分布式应用程序和场景,特别是那些需要高性能、低延迟和可靠性的应用。
⻆色 | 作用 |
---|---|
Nameserver | 无状态,动态列表;这是和 ZooKeeper 的重要区别之一。ZooKeeper 是有状态的。 |
Producer | 消息生产者,负责发消息到 Broker。 |
Broker | 就是 MQ 本身,负责收发消息、持久化消息等。 |
Consumer | 消息消费者,负责从 Broker 上拉取消息进行消费,消费完进行 ack。 |
queue 就是来源于数据结构的 FIFO 队列。而 Topic 是个抽象的概念,每个 Topic 底层对 应 N 个 queue,而数据也真实存在 queue 上的。
消费模型由 Consumer 决定,消费维度为 Topic。
集群消费
- 一条消息只会被同 Group 中的一个 Consumer 消费
- 多个 Group 同时消费一个 Topic 时,每个 Group 都会有一个 Consumer 消费到数据。
广播消费
- 消息将对一个 Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些Consumer 属于同一个Consumer Group,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
RocketMQ的Consumer消费消息的方式有两种:Push方式和Pull方式。
- 在 Push 推模式下,RocketMQ 的 Broker 会主动将消息推送给对应的 Consumer。而 Consumer 会注册一个 MessageListener 回调函数,并在接收到消息后立即触发回调函数。
- 在 Pull 拉模式下,Consumer 需要主动向 Broker 定期发送拉取消息的请求,自行完成处理消息,以及向 Broker 返回 ack 信息等步骤。
这两种模式都有各自的优缺点,适合不同的业务场景。其中:
- Push 模式的优点是,实现比较简单,客户端只要注册回调方法,专心处理业务就可以了。并且消息到达 Broker 后立即会被推送到 Consumer,消息处理比较及时。缺点也比较明显,消费者需要与 Broker保持长时间的连接,对网络要求比较高。
- Push 模式的有点是,Consumer 有更大的控制权,可以根据自身处理能力来调整拉取消息的频率,避免消息积压。并且拉模式只需要在拉取消息时与 Broker 保持短暂的网络连接,比较适合那些网络连接不是很稳定的环境。而对应的缺点则是,Pull 模式下,Consumer 需要自行调整消息拉取的频率,处理消息就没有 Push 模式那么及时。另外,Push 模式下,Consumer 的实现相对比较复杂,容易产生消息积压。
不论是Push方式还是Pull方式,从Broker获取消息后,Consumer都会进行消费处理。RocketMQ还提供了多种消费策略,如集群消费、广播消费、并行消费和顺序消费等,以满足不同的业务需求。
Consumer 首次请求 Broker。
- Broker 中是否有符合条件的消息
- 有
- 响应 Consumer。
- 等待下次 Consumer 的请求。
- 没有
- DefaultMessageStore#ReputMessageService#run 方法。 - PullRequestHoldService 来 Hold 连接,每个 5s 执行一次检查pullRequestTable 有没有消息,有的话立即推送。
- 每隔 1ms 检查 commitLog 中是否有新消息,有的话写入到pullRequestTable。
- 当有新消息的时候返回请求。
- 挂起 consumer 的请求,即不断开连接,也不返回数据。
- 使用 consumer 的 offset。
通过 Topic 在多 Broker 中分布式存储实现。
producer 端
发送端指定 message queue 发送消息到相应的 broker,来达到写入时的负载均衡
- 提升写入吞吐量,当多个 producer 同时向一个 broker 写入数据的时候,性能会下降 - 消息分布在多 broker中,为负载消费做准备
默认策略是随机选择:
- producer 维护一个 index
- 每次取节点会自增
- index 向所有 broker 个数取余
- 自带容错策略
其他实现:
- SelectMessageQueueByHash
- hash 的是传入的 args
- SelectMessageQueueByRandom
- SelectMessageQueueByMachineRoom 没有实现
也可以自定义实现 MessageQueueSelector 接口中的 select 方法
MESSAGEQUEUE SELECT(FINAL LIST
MQS, FINAL MESSAGE MSG, FINAL OBJECT ARG);
consumer 端
采用的是平均分配算法来进行负载均衡。
其他负载均衡算法
平均分配策略(默认)(AllocateMessageQueueAveragely) 、环形分配策略(AllocateMessageQueueAveragelyByCircle) 、手动配置分配策略(AllocateMessageQueueByConfig) 、机房分配策略 (AllocateMessageQueueByMachineRoom)、一致性哈希分配策略 (AllocateMessageQueueConsistentHash)、靠近机房策略 (AllocateMachineRoomNearby)
追问:当消费负载均衡 consumer 和 queue 不对等的时候会发生什么?
Consumer 和 queue 会优先平均分配,如果 Consumer 少于 queue 的个数,则会存在部分Consumer 消费多个queue 的情况,如果 Consumer 等于 queue 的个数,那就是一 个 Consumer 消费一个 queue,如果 Consumer个数大于 queue 的个数,那么会有部分 Consumer 空余出来,白白的浪费了。
影响消息正常发送和消费的重要原因是网络的不确定性。
引起重复消费的原因
- ACK
正常情况下在 consumer 真正消费完消息后应该发送 ack,通知 broker 该消息 已正常消费,从 queue 中剔除。
当 ack 因为网络原因无法发送到 broker,broker 会认为词条消息没有被消费, 此后会开启消息重投机制把消息再次投递到 consumer- 消费模式
在 CLUSTERING模式下,消息在 broker 中会保证相同 group 的 consumer 消 费一次,但是针对不同 group 的consumer 会推送多次解决方案
- 数据库表
处理消息前,使用消息主键在表中带有约束的字段中 insert- Map
单机时可以使用 map ConcurrentHashMap -> putIfAbsent guava cache - Redis
分布式锁搞起来。
首先在如下三个部分都可能会出现丢失消息的情况:
- Producer 端
- Broker 端
- Consumer 端
Producer 端如何保证消息不丢失
- 采取 send()同步发消息,发送结果是同步感知的。
- 发送失败后可以重试,设置重试次数。默认 3 次。PRODUCER.SETRETRYTIMESWHENSENDFAILED(10);
集群部署,比如发送失败了的原因可能是当前 Broker 宕机了,重试的时候会发送到其他 Broker 上。
Broker 端如何保证消息不丢失
- 修改刷盘策略为同步刷盘。默认情况下是异步刷盘的,将刷盘方式(FlushDiskType)配置为 Sync 同步刷盘,保证消息尽快写入到磁盘中,防止 Broker 出现故障造成内存中没有及时刷如到硬盘的那一部分消息丢失。
- 集群部署,主从模式,高可用。为了防止 Broker 端硬盘出现故障造成消息丢失,给 Broker 配置一个或多个 Slave 从节点,进行消息冗余。同时将消息同步方式配置为 Sync 同步同步。
Consumer 端如何保证消息不丢失
- 完全消费正常后在进行手动 ack 确认。
开发
- 同一 group 下,多机部署,并行消费 - 单个 Consumer 提高消费线程个数 - 批量消费
- 消息批量拉取
- 业务逻辑批量处理
运维
- 网卡调优
- jvm 调优
- 多线程与 cpu 调优 - Page Cache
RocketMQ的集群架构包括四个主要角色:Name Server集群、Broker主从集群、Producer和Consumer客户端。
- Name Server集群是RocketMQ的一种轻量级的服务节点,负责注册和管理Broker的服务地址,提供服务的注册和发现功能。每个Broker节点都要跟所有的Name Server节点建立长连接,定义注册Topic路由信息和发送心跳。每个 NameServer 节点都会保存完整的 Broker 列表数据,并且 NameServer 个个节点之间不会同步数据。因此,NameServer 集群不会因为单个节点发生故障而停止服务。
- Broker 是 RocketMQ 的核心组件,负责存储和传输消息。一个 RocketMQ 集群通常包含多个 Broker 实例,共同协作来提高 RocketMQ 的可用性和吞吐量。其中,Master Broker,主节点,负责处理客户端的请求,并将消息存储到磁盘上,然后将消息同步复制给所有的从节点。而从节点,是Master Broker 的消息备份。
- 客户端包含 Producer 生产者和 Consumer 消费者。其中,Producer 负责将消息发送给 Broker。Producer 可以将消息发送到指定的 Topic,RocketMQ 会负责将消息存放到对应的 Broker 上。Consumer 可以订阅一个或多个 Topic,并从对应的 Broker 上接收消息进行处理。RocketMQ 的客户端提供了多种处理消息的方式,比如延迟消息、事务消息、集群消息、广播消息等。
RocketMQ的Broker有三种集群模式:
- 单Master模式:只有一个Master节点,其他都是Slave节点。Master节点负责响应客户端的请求并存储消息,Slave节点只同步Master节点的消息,也会响应部分客户端的读请求。这种模式的优点是简单易部署,但是存在单点故障的问题,如果Master节点宕机,会导致整个服务不可用。
- Master-Slave模式(经典双集群部署):一个Master节点对应多个Slave节点,Master和Slave都是独立的NameServer。Master节点负责响应客户端请求并存储消息,Slave节点只同步Master节点的消息,也会响应部分客户端的读请求。这种模式的优点是高可用性,即使Master节点宕机,Slave节点可以自动升级为Master节点,继续提供服务。但是,如果只有一个Master节点,存在单点故障的问题。
- Dledger模式(高可用集群部署):在Master-Slave模式的基础上增加了Raft协议,实现了自动脑裂后的数据高可靠性。即使某个节点从网络上掉下来或者宕机后,仍然能够保证所有的消息不会丢失。这种模式的优点是高可用性和高可靠性,即使某个节点出现故障,也能保证服务的可用性。
总的来说,单Master模式适合测试和开发环境,Master-Slave模式适合生产环境,而Dledger模式适合需要高可靠性的生产环境。
在RocketMQ中,如果未消费的消息过多,会给集群带来非常多的问题:
- 消息堆积:消息在Broker端不断堆积,可能会导致Broker的存储压力过大,影响整个系统的性能和稳定性。
- 死信队列:RocketMQ中的Broker会在一定时间内无法被消费的消息转换到死信队列中。如果消息持续堆积,死信队列的空间有限,一些消息可能会被丢弃,导致数据丢失。
- 消息延迟和积压:如果消息持续堆积,可能会导致消息的延迟增大,进一步影响系统的响应速度和处理能力。
- 消息丢失:RocketMQ 会定期删除过期的日志文件。在删除时,RocketMQ并不会关注过期文件中的消息是否被消费者处理。这就会造成过期日志文件中未被 Consumer 消费的消息丢失。
为了避免这些问题,可以采取以下措施:
- 控制消息发送速度:Producer可以根据Consumer的处理能力,动态地控制消息的发送速度。例如,可以通过监控Consumer的处理情况,调整发送速度,避免消息堆积。
- 增加Consumer:可以增加更多的Consumer来提高消息的消费能力。通过增加Consumer的数量,可以并行处理消息,提高系统的吞吐量。
- 及时处理死信队列:可以在Broker端配置死信队列,对无法正常被消费的消息进行捕获和处理。这样即使消息被丢弃,也可以通过死信队列进行恢复和处理。
- 合理配置Broker和Producer/Consumer的参数:可以通过调整Broker和Producer/Consumer的配置参数,如缓存大小、请求超时等,来优化系统的性能和稳定性。
综合来说,合理的配置和监控是避免生产者速率超过消费者速率的关键。根据实际业务需求和资源配置,可以选择适当的措施来优化消息的处理,以确保消息队列系统的稳定和高性能。
RocketMQ的延迟消息实现是通过在消息发送时设置一个延迟级别,然后消息会被存储到DelayMessageService中,等待达到指定的延迟时间后再被重新推送到Broker的commitLog服务中。
具体流程如下:
- Producer 将消息投递到Broker的commitLog服务。
- commitLog服务判断消息是否为延迟消息,如果是,则将实际的topic和queueId保存到消息的属性中,并将topic设置成延迟topic(SCHEDULE_TOPIC_XXXX),queueId对应的延迟级别和消息投递时间保存在tagCode中。
- 消息延迟服务(DelayMessageService)从SCHEDULE_TOPIC_XXXX主题循环拉取消息。
- DelayMessageService根据tagCode找到对应的延迟队列,并按照延迟级别进行排序。
- 当达到指定的延迟时间后,DelayMessageService会将消息重新推送到commitLog服务。
- commitLog服务将消息推到Producer 指定的目标 Topic 中。
- Consumer从 目标 Topic 中拉取消息。
RocketMQ支持最多18个延迟级别,可以满足不同延迟时间的需求。
另外,在新版本的 RocketMQ 中,使用时间轮机制,提供了指定任意时间的延迟消息功能。
RocketMQ可以通过以下优化措施来处理大量的消息:
- 增加Broker数量:增加Broker数量可以使得消息在消费端的负载均衡更加灵活,同时可以提高系统的容错性和可用性。
- 消息生产者的异步发送: 消息生产者可以使用异步发送方式,以降低发送消息的延迟,提高发送吞吐量。异步发送允许生产者在等待确认之前继续发送更多的消息。
- 使用批量发送和批量消费: RocketMQ 支持批量发送消息和批量消费消息。批量操作可以减少网络开销和提高处理效率,特别是在高吞吐量的场景下。使用批量发送和批量消费可以显著减少网络负载和提高性能。
- 合理设置消费者数量:增加消费者数量可以显著提升消费者处理消息的并发能力。但是,消费者数量不能超过对应 Topic 中的 MessageQueue 数量。另外,增加消费者的工作线程数,也能一定程度上提升消费者的处理性能。
- 优化JVM参数:通过调整JVM参数可以使得系统更加稳定,减少因为垃圾回收导致的性能下降。
- 使用硬件加速:可以通过使用SSD等更快的存储设备来提高I/O性能,从而加快消息的处理速度。
总之,处理大量消息需要综合考虑多个因素,包括集群配置、性能优化、顺序消息处理、分区等。通过合理的配置和优化,可以实现高吞吐量和高性能的消息处理。同时,要根据业务需求和负载情况不断进行性能监测和调整,以保持系统的稳定性和可伸缩性。
RocketMQ 提供了消息存储清理和归档的机制,以便管理消息存储空间,删除过期消息,并将历史消息归档到其他存储介质中。这些功能有助于维护消息队列的性能和可用性。以下是关于 RocketMQ 消息存储清理和归档的主要方面:
- 消息文件删除策略: RocketMQ 支持多种消息文件删除策略,可以在配置文件中进行设置。以下是一些常见的策略:
- 定时删除策略: 您可以配置 RocketMQ 定期删除过期的消息文件和索引文件。这样,一旦消息文件中的消息过期,RocketMQ 将自动删除它们。
- 空间满策略: 如果存储磁盘空间达到一定限制,RocketMQ 可以自动删除最早的消息文件,以释放磁盘空间。这个策略确保了存储空间不会无限制地增长。
- 指定时间段删除策略: 您可以配置 RocketMQ 只删除特定时间段内的消息文件,以保留历史消息。
- 消息归档: RocketMQ 允许您将历史消息归档到其他存储介质中,以减小消息服务器的存储负担。归档通常涉及将消息转移到长期存储(如云存储或本地归档系统)中。归档可以手动触发,也可以自动触发,具体取决于您的需求。
- 历史消息访问: 尽管消息被归档,RocketMQ 仍然提供了访问历史消息的机制。通过合适的归档系统或者存储介质,您可以检索和访问历史消息,以满足合规性要求或其他业务需求。
需要注意的是,清理和归档消息不是 RocketMQ 的核心功能,而是辅助功能。您需要根据自己的需求和业务场景来配置和管理消息的清理和归档策略。确保配置合理的清理策略以防止存储空间耗尽,并根据业务需求进行消息的归档操作,以保留历史消息数据。同时,归档后的消息可以根据需要进行合适的检索和恢复,以满足特定的数据需求。
RocketMQ是采用分布式存储的方式来存储消息的。每个Broker的存储结构主要包括:CommitLog、ConsumeQueue和IndexFile。
- CommitLog是消息存储的物理文件,存储了所有消息的主题、标签、时间戳等基本信息和消息体。每个Broker上的CommitLog被当前机器上的所有ConsumeQueue共享。
- ConsumeQueue是消息的逻辑队列,存储了具有相同属性(如Topic、队列ID等)的消息。每个Broker上有多个ConsumeQueue,每个Topic的消息都对应一个ConsumeQueue。Consu meQueue采用顺序写入、随机读取的方式存储消息,同时支持高效的预写日志和刷盘策略。
- IndexFile是消息索引文件,存储了消息在CommitLog中的偏移量和消息物理偏移量对应关系,采用Hash索引方式加速定位。
RocketMQ通过这种分布式存储方式可以高效地存储和访问大量消息,同时也具有良好的可扩展性和可靠性。
RocketMQ的事务消息是通过两阶段提交(Two-phase Commit)协议实现的。具体实现步骤如下:
- 发送方将半事务消息发送至RocketMQ服务端,由于消息为半事务消息,在未收到生产者对该消息的二次确认前,此消息被标记成“暂不能投递”状态,不会被消费。
- 发送方开始执行本地事务逻辑。可能是一系列的数据库更新、文件写入等操作,他们要么全部成功,要么全部回滚。
- 发送方根据本地事务执行结果向服务端提交二次确认(Commit 或是 Rollback),服务端收到 Commit 状态则将半事务消息标记为可投递,订阅方最终将收到该消息;服务端收到 Rollback 状态则删除半事务消息,订阅方将不会接受该消息。
- 如果二次确认时,发送方的本地事务没有执行完成,则可以向服务端返回 Unknown 状态,服务端收到 Unknown 状态则会等一段时间后,重新向发送放发起状态确认。如果发送方多次返回 Unknown 状态,服务端则会直接丢弃这一条消息。
RocketMQ 的事务消息机制是为了解决分布式事务问题而设计的,它适用于需要确保一系列操作的一致性的场景,如订单支付、库存扣减、资金结算等。主要的用途有:
- 分布式事务: 事务消息用于支持分布式系统中的分布式事务。它可以确保涉及多个操作的事务要么全部成功,要么全部失败,以维护数据的一致性。典型的应用包括订单支付、库存扣减、资金结算等。
- 消息可靠性: 事务消息与普通消息一样,具有消息的可靠性传递特性。一旦事务消息被成功发送到 RocketMQ 服务器,它将被存储和传递,不会丢失。
- Exactly Once 语义: RocketMQ 事务消息提供了"Exactly Once"语义,确保消息要么完全提交,要么完全回滚,不会出现部分提交或回滚的情况。
使用事务消息,您可以更好地处理这些复杂的业务流程,确保数据的完整性和一致性。但请注意,事务消息也需要谨慎使用,因为它可能会引入一些复杂性,并影响系统的性能和可伸缩性。
RocketMQ 提供了顺序消息机制,用来保证一组消息的局部有序性,具体实现步骤如下:
- Producer 在发送消息时,通过设置一个 MessageQueueSelector 方法,将一组有顺序的消息,依次发送到对应 Topic 下的同一个 MessageQueue 上。而 MessageQueue 是能够保证 FIFO 先进先出的,这样就可以保证一组有顺序的消息在 Broker 上是有序的。
- Consumer 在配置 MessageListener 时,需要指定为 MessageListenerOrderly 实现类。这样就能保证一组有序的消息可以按照发送时的顺序进入 Consumer 进行处理,从而保证这一组消息的顺序。
但是在使用顺序消息时,有几个需要注意的问题:
- RocketMQ 的顺序消息机制只保证一组消息的局部有序性,而并不保证所有消息的全局有序性。应用需要自行定义消息中的一些标识符来确定消息的顺序。
- 顺序消息机制会给 MessageQueue 添加线程锁,这会降低 Consumer 的消息吞吐量。
- 如果 Consumer 消费消息出现错误,会将整个 MessageQueue 阻塞,而无法单独重试这一条消息。这样非常容易导致 Topic产生大量的消息积压,因此使用顺序消息要尽量保证 Consumer 的消息处理正确性。
广播消息和集群消息是 RocketMQ 的两种不同的消息消费模式。其中
- 广播模式意味着一条消息会被发送到所有订阅了这个主题 Topic 的消费者,而所有消费者都会收到相同的消息副本。
- 集群模式意味着一条消息只会分发给订阅了这个主题 Topic 的同一个消费者组中的一个消费者处理。每个消费者组只会处理一次消息。
他们的区别主要提现在实现方式以及适用场景上。
- 集群模式在 Broker 端统一管理每个消费者组的消费进度,对消费进度的管理是严格的。这样,每次消费者服务启动后,都可以从上一次消费的进度开始开始进行消费。 而广播模式是交由每个消费者自行管理消费进度,消费进度的管理是不严格的,容易产生丢失。当消费者服务启动后,如果本地的消费进度丢失了,就只能消费到启动之后的消息,而无法从上一次消费的进度开始消费。因此,广播模式对于消息的连续性保证是不强的。
- 集群模式适用于大多数常规对消息安全敏感的业务场景,例如订单处理、库存管理等。多个消费者协同工作可以提高消息的处理能力并实现消息的负载均衡。而广播模式适用于一些对消息安全不太敏感的特殊业务场景。例如日记记录、时间通知等。这些场景下所有的消费者都需要处理相同的消息。
RocketMQ消息过滤分为两种:基于表达式的过滤和基于类模式的过滤。
基于表达式的过滤有两种模式:TAG模式和SQL92模式。其中,RocketMQ 允许为每一条消息设置一个 Tag 标签。
- TAG 模式下,Consumer 可以选择订阅特定的 TAG,对消息进行过滤。TAG模式根据消息的属性进行过滤,适合于简单的场景;SQL92模式可以支持更复杂的逻辑,可以使用SQL92的语法进行过滤。这种过滤方式由于是在 ConsumeQueue 文件中直接进行过滤,所以性能比较高。
- SQL92 模式下,Consumer 可以通过设定一个满足 SQL92 标准的 SQL 语句,定制相对比较复杂的过滤逻辑,例如数值比较等。同时,也可以引用消息中添加的其他自定义属性,定制多维度的过滤条件组合。
基于类模式的过滤是使用用户自定义的过滤器类来实现消息过滤。消费者可以在消息监听器中编写自定义逻辑来实现更复杂的消息过滤机制。在这种模式下,消费者可以完全控制消息的过滤逻辑,适用于需要导读定制和特殊处理的场景。但是同样,对Consumer 的编码能力要求更高。
RocketMQ 在进行消息过滤时,都会将消息过滤的逻辑上推到 Broker 端执行。这样可以减少不必要的网络数据传递。但是,同时也会给 Broker 增加业务复杂性。因此,客户端需要根据不同的业务场景,选择合适的过滤机制。
RocketMQ的Producer有三种消息发送模式,RocketMQ允许在不同的场景下使用不同的消息发送模式,以满足不同的业务需求。:
- 同步发送(Sync Send):这是默认的发送模式。在同步发送模式下,发送者发送一条消息后会等待 Broker 的响应,直到 Broker 确认收到消息并返回结果。如果发送失败,将会抛出异常。这种模式下,Producer 可以确保消息成功发送到了 Broker,消息安全性更高。但是,由于需要等待 Broker 的响应,可能会引起较大的发送消息延迟。
- 异步发送(Async Send):这种模式下,Producer发送消息后不会等待Broker的响应,而是继续执行后续操作。Producer可以注册回调函数,在消息发送完成后Broker会异步调用回调函数。这种模式可以提高 Producer 的吞吐量和响应速度,但是,Producer 需要在回调函数中自行处理 Broker 的消息响应,对客户端代码要求较高。并且,在这种模式下,如果消息发送出现问题,Producer 只能通过回调函数处理,这样 Producer 处理消息错误的时机是有延迟的。
- 单向发送(Oneway Send):这种模式下,Producer 发送消息后不关心消息是否被 Broker 成功接收和存储,也不等待 Broker 的响应。这样,Producer 发送消息的效率是最高的。但是,消息的安全性就无法保证。这种模式通常适用于那些强调消息吞吐量而不关心消息可靠性的场景,例如日志消息。