【源码解析】Apache RocketMQ发送消息源码

send message源码解析

引入

send message方法作为我们经常使用的方法,平时我们很难去关注他底层到底做了什么。大部分人只知道通过send message方法可以将消息发送到broker,然后供消费者进行消费。其实不然,消息从客户端发送到broker,需要中间需要经过很多步骤,比如:首先客户端需要向nameserver拿路由,拿到路由后才能将消息发送到对应的broker。消息到了broker,需要先进行校验,校验无误后,再写到commitLog,写完commitLog后,再根据具体的策略判断是否需要同步到slave节点,同步完slave节点完后才response给客户端。

源码阅读入口

java 复制代码
// 客户端入口
org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl

// NameServer入口
org.apache.rocketmq.namesrv.processor.ClientRequestProcessor#getRouteInfoByTopic

// Broker端入口
org.apache.rocketmq.broker.processor.SendMessageProcessor#processRequest

源码解析

  • RocketMQ中的客户端send方法提供了单条发送发送也批量发送的API,不管是单条发送还是批量发送本质都是一样的,批量发送会把消息集合包装一下了,具体可以看batch里面的实现,将消息集合封装了MessageBatch对象,当然MessageBatch继承Message。然后再尝试去topicPublishInfoTable中拿路由,如果没有就请求NameServer(忽略经过Proxy层),需要注意的是,请求NameServer获取路由的这个过程是同步的,同一时间只有一个线程可以请求NameServer,需要等到NameServer返回之后才会执行后续的操作。拿到路由后再根据轮询策略选中其中一个broker进行发送。这就是发送消息客户端大致的逻辑,总体来说是还是比较简单的。
  • CONSUMER_SEND_MSG_BACK是消费者发过来的RETRY消息,本次重点不在这里,后续单独讲下这里。当消息到达Broker'端,先根据请求头构建出一个MappingContext对象,再把request对象封装成sendMessageContext;执行注册到sendMessageProcessor里面的钩子方法sendMessageBefore;之后根据是否是batch消息,如果是batch消息,执行sendBatchMessage,不是执行sendMessage方法,其实本质上还是一样的,只是sendBatchMessage中间构建的是messageExtBatch对象,而sendMessage构建的是messageExtBrokerInner对象。MessageExtBatch是MessageExtBrokerInner的子类,所以两者后续还是共用一套逻辑;然后根据是否开启异步写入执行asyncPutMessage或者putMessage,同步的putMessage实际上还是调用的asynPutMessage,只是要等到asyncPutMessage有返回值之后才执行后续的逻辑。我们这里以asyncPutMessage为主,还是先执行注册到SendMessageProcessor里面的钩子方法SendMessageAfter,然后再先判断时候是否是HA(高可用,高可用是需要等到消息写入slave节点成功之后才说明消息发送成功,一般使用在一些金融场景,对消息可靠性要求较高。),然后再然后分配offset(这个offset是由consumeQueue分配的),分配完offset之后,分配完了之后,再将消息体append到commitLog的分配的buf中,返回的状态码PUT_OK执行handleDiskFlush方法,如果是配置的是同步刷盘就等到刷盘成功后返回,如果是异步刷盘,wakeup对应的FlushManager就算写入完成。
  • 上述执行成功后,执行handleHA方法,如果是不是HA模式执行response PUT_OK,否则,构建一个GroupCommitRequest对象put到haService里面,对应slave节点写完最终才算发送成功。

参考:

· https://rocketmq.apache.org/

· 基于Apache Rocket 5.1.0

· https://github.com/apache/rocketmq

相关推荐
心易行者14 小时前
Agent应用+API端点商业化进阶实战:从单体智能体到可付费调用的API全流程
运维·服务器·人工智能·python·apache
MayBaymax2 天前
RocketMQ 存储机制
java·rocketmq
文慧的科技江湖6 天前
2026年10月4日充电桩行业晚报:当“只充80%“成为通行规则,行业开始管单车占桩时长 | 慧知开源充电桩平台
开源·apache·新能源·虚拟电厂·充电桩·ocpp·v2g
此时不提桶,更待何时8 天前
06-07-A-RocketMQ生态集成详解
rocketmq
妄汐霜8 天前
SSE,RocketMQ,MQTT不同之处
笔记·学习·rocketmq
nvd118 天前
# 从 192 秒到 13 秒:Apache Flink 批处理极速调优实战记录
大数据·flink·apache
众链网络9 天前
景区票务系统选型的技术尽调清单:从并发、数据到二次开发的 12 个必查项
apache·景区票务系统
IT机器猫9 天前
RocketMQ基础一
rocketmq
蚂蚁背大象10 天前
RocketMQ-Rust 1.0.0 发布:用 Rust 做消息队列,这次有哪些变化?
rust·开源·rocketmq
此时不提桶,更待何时10 天前
06-08-B-RocketMQ面试与生产事故实战
面试·rocketmq