「日拱一卒」带你探索RocketMQ消息发送(七)

82 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

前言

上一篇文章「日拱一卒」带你探索RocketMQ消息发送(六),我们一起学习了 RocketMQ 选择消息发送队列的机制,选择了合适的队列后,就可以进行消息的发送了。今天我们一起来探索消息发送的源码吧~

消息发送

消息发送的主要逻辑是在这个方法中DefaultMQProducerImpl#sendKernelImpl:

image.png

每个参数的含义是:

  • Message msg:待发送的消息
  • MessageQueue mq:消息将发送到的消息队列上
  • CommunicationMode communicationMode:消息发送的模式:Sync、ASync、Oneway
  • SendCallback sendCallback:异步消息回调函数
  • TopicPublishInfo topicPublishInfo:Topic 路由信息
  • long timeout:消息发送超时时间

我们一起来看看该方法主要干了些啥吧?

  1. 首先,根据 MessageQueue 来获取 Broker 的 IP 地址,其实就是将 MessageQueue 携带的 BrokerName 信息作为 Key,去 brokerAddrTable 这个 ConcurrentHashMap 中查询到对应的 Broker 信息,如果查到了,则返回:

image.png

  • 如果查询不到,即为 null ,则从 NameServer 中主动查询并更新 Topic 路由信息到 brokerAddrTable 中缓存起来,然后再从缓存中 Get 出来:

image.png

  1. 如果消息不是批量消息,则为该消息分配全局唯一ID;如果 ClientConfig 配置文件中有 namespace ,那么则把 namespace 赋值给该消息的 InstanceID 属性;如果消息的大小超过了 4MB,则采用 zip 算法进行压缩,并将消息的系统标记为 MessageSysFlag.COMPRESSED_FLAG ;如果消息是 TRAN_MSG 事务消息,则将该消息的系统标记为 MessageSysFlag.TRANSACTION_PREPARED_TYPE

image.png

  1. 如果注册了消息发送的钩子函数,则会执行消息发送前的增强逻辑。代码如下:

image.png

  1. 构造发送消息的RequestHeader,包含这些属性:生产者组、Topic名称、默认创建 Topic 的Key、该 Topic 在单个 Broker 上的默认队列数、队列 ID、消息系统标记、消息发送时间、消息标记、消息扩展属性、消息重试次数、是否是批量消息,组装完成后,就可以进行发送了

image.png

  1. 根据消息发送方式进行网络传输,并获取返回结果 SendResult
  • 异步的方式,主要会传递一个回调接口:

image.png

  • 同步的方式,比异步方式简单一些:

image.png

  • 单向发送,由于不需要知道消息发送的结果,所以这里什么都不做
  1. 如果注册了消息发送钩子函数,执行消息发送完成后的逻辑

image.png

小结

消息发送的核心逻辑在 DefaultMQProducerImpl#sendKernelImpl 方法中,仔细看代码还是挺有意思的,明天会再给大家分别讲解同步发送、异步发送、单向发送的具体实现逻辑,大家多多关注~