RocketMQ Producer发送消息过程

说明

在Producer启动完成后,就可以利用Producer向Broker发送消息,我们以最简单的发送同步消息进行流程讲解。发送消息的核心逻辑分三个步骤:
1、根据Topic获取路由信息;
2、选择消息发送的目标队列;
3、发送消息到Broker。

消息发送入口

Producer发送消息的入口在DefaultMQProducer类的send()方法,DefaultMQProducer提供了很多重载的方法,这些重载方法,内部调用了DefaultMQProducerImpl内的send方法,发送的核心逻辑就在该类的sendDefaultImpl()方法内
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面,我们分步骤看一下每个主要步骤的逻辑。

根据Topic获取路由信息

DefaultMQProducerImpl的tryToFindTopicPublishInfo方法,将获取到的Topic路由信息(TopicRouteData)封装成TopicPublishInfo。这里先会根据指定的topic获取路由信息,如果获取不到,则会使用默认的topic(TBW102,DefaultMQProducer类createTopicKey属性定义)再获取一次
在这里插入图片描述
接着我们进入MQClientInstance.updateTopicRouteInfoFromNameServer()方法:该方法是通过MQClientAPIImpl.getTopicRouteInfoFromNameServer()方法获取路由信息。
在这里插入图片描述
进入MQClientAPIImpl.getTopicRouteInfoFromNameServer()方法:该方法其实很简单,构造请求命令->发送请求指令->解析结果。
在这里插入图片描述
获取到的路由信息,包括队列数据、Broker数据和Broker地址信息:
在这里插入图片描述
在获取到topic的路由信息后,我们再回到MQClientInstance.updateTopicRouteInfoFromNameServer()方法:判断MQClientInstance.topicRouteTable属性以前缓存的路由信息是否需要更新、DefaultMQProducerImpl.topicPublishInfoTable属性以前缓存的路由信息是否需要更新
在这里插入图片描述
如果需要更新:
在这里插入图片描述
更新完之后,DefaultMQProducerImpl.tryToFindTopicPublishInfo()方法就可以从缓存(Map)中获取Topic的路由信息TopicRouteInfo了。TopicRouteInfo结构
在这里插入图片描述
所以,整个流程如下(实线为请求过程,虚线为响应过程):
在这里插入图片描述

选择消息发送的目标队列

在获取到topic的路由信息后,将选择消息发送的目标队列。DefaultMQProducerImpl.selectOneMessageQueue()方法是通过MQFaultStrategy.selectOneMessageQueue()方法实现的。这里分两种情况讨论:
1、如果开启延迟容错策略(producer.setSendLatencyFaultEnable(true)),则要考虑Broker的响应时间。
这里解释一下延迟容错策略,它指的是要考虑Broker的响应时间。如果Broker响应缓慢,则我们选择队列时,就不应该选择该Broker,而应该选择响应更快的Broker里的队列。Broker的响应时间是在消息发送阶段采集的:
在这里插入图片描述
如果Broker响应时间达到一定的标准,则一段时间内认为该Broker尽量不要选用,这个标准定义在MQFaultStrategy(没错,源码是直接写死的)
在这里插入图片描述
明白了延迟容错策略后,我们再来看看开启了延迟容错策略后如何选择消息发送的队列
在这里插入图片描述
步骤:
1、遍历topic路由信息里的队列,看队列对应的Broker是否健康,如果健康,则直接返回该队列;
2、如果遍历了所有队列后,依然没有找到比较健康的Broker,则择优取一个,择优规则(择优规则通过FaultItem的排序实现)按以下规则进行:
(1)、哪个Broker健康,哪个优先被选择。
(2)、哪个Broker响应较快,哪个优先被选择。
(3)、哪个Broker剩余不可用时间越小,哪个优先被选择。
在这里插入图片描述
2、如果没有开启延迟容错策略,则直接从Topic路由信息获取
在这里插入图片描述
第一次随机,后续往后选另一个Broker的队列
在这里插入图片描述

发送消息到Broker

队列选好后,就是发送消息了。发送消息的核心逻辑在DefaultMQProducerImpl.sendKernelImpl()方法
在这里插入图片描述
在这里插入图片描述
最终通过NettyRemotingClient的同步调用,发送同步消息
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐观男孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值