【源码解析】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

相关推荐
喂完待续6 小时前
【Tech Arch】Hive技术解析:大数据仓库的SQL桥梁
大数据·数据仓库·hive·hadoop·sql·apache
SelectDB7 小时前
5000+ 中大型企业首选的 Doris,在稳定性的提升上究竟花了多大的功夫?
大数据·数据库·apache
喂完待续20 小时前
Apache Hudi:数据湖的实时革命
大数据·数据仓库·分布式·架构·apache·数据库架构
数据爬坡ing2 天前
过程设计工具深度解析-软件工程之详细设计(补充篇)
大数据·数据结构·算法·apache·软件工程·软件构建·设计语言
运维行者_2 天前
使用Applications Manager进行 Apache Solr 监控
运维·网络·数据库·网络安全·云计算·apache·solr
皓空揽月2 天前
php+apache+nginx 更换域名
nginx·php·apache
求知若渴,虚心若愚。4 天前
高可用实战之Nginx + Apache篇
运维·nginx·apache
富士康质检员张全蛋4 天前
RocketMQ 消息存储机制 CommitLog和ConsumerQu
rocketmq
阿里云云原生5 天前
Apache RocketMQ EventBridge:为什么 GenAI 需要 EDA?
apache·rocketmq
创码小奇客5 天前
架构师选型圣经:SpringBoot 集成三大消息中间件的终极对决
rabbitmq·rocketmq·trae