RocketMQ生产者消费者部分源码分析总结

前言:这是在查看源码时生产者消费者初始化的部分源码的思路的记录

1. 生产者初始化

1、mq开启的时候会检查相关配置:生产组是否配置,必须配置且不能为null也不能为DEFAULT_PRODUCER

2、生产者实例名的设置,若未主动设置,则采用默认的配置,生成的实例名(格式):pid@hostname的@符号前的数字使用字符串格式化

3、获得生产者的真正意义上的实例,并且以组名为key值,将其缓存在缓存中(此处,生产者与组应是一一对应),生产组在缓存已存在,不能重复放入,否则失败。

4、topicPublishInfoTable会初始化一个默认的topic信息,TBW102

5、MQ客户端实例开启

6、向所有的broker发送心跳

2. 普通消息发送

1、从缓存获取当前要发送消息的topic的TopicPublishInfo,没有则从nameserver更新

2、缓存的每个生产者都要更新下最新的TopicPublishInfo

3、更新topic的订阅信息

4、在小于重试次数且消息未发送成功的条件下,选取一条消息队列,第一次随机选取,队列=(随机数%(总队列数=各个broker队列数之和)),下次轮询为当前队列数加1下

3. 事物消息发送

1、事物消息发送需要传入一个LocalTransactionExecuter本地回调的函数对象(一阶段开始)

2、校验该函数对象不能为null

3、普通消息发送开始发送消息

4、函数回调,本地事务函数对象执行(一阶段结束,二阶段开始)

5、判断事务是否处理成功,返回类型为[COMMIT_MESSAGE,ROLLBACK_MESSAGE,UNKNOW]

6、设置好请求头,根据返回类型进行相应的响应

事务处理结束(二阶段结束)

commitLog中会存有消息的(topic就叫ThirdTopic),普通的消息描述

ThirdTopic vPGROUPTXPRODUCER_THIRDTOPIC_GROUPTAGSluoyKEYS13951818259UNIQ_KEYC0A85C0B220408FD9B4D62BDB0F00000TRAN_MSGtrue ڣ w_

发送失败还是成功,只剩带事务标记的消息

ThirdTopic vPGROUPTXPRODUCER_THIRDTOPIC_GROUPTAGSluoyKEYS13951818259TRAN_MSGtrueUNIQ_KEYC0A85C0B220408FD9B4D62BDB0F00000

4. consumer高可用

consumer启动时,如果name server或broker挂掉或连接失败,依然可以成功启动,不会报异常,等到连接恢复,consumer会定时发送心跳感知到,之后会继续正常进行消费。

5. topic订阅

1、初始化订阅的topic的相关信息

2、将该topic及其订阅信息放入负载实现类里

3、若MQClientInstance实例未初始化(启动时会初始化),则不发送心跳给所有broker

6. 消费者启动

1、检查相关配置(消费队列分配策略、订阅信息、回调的消息监听器类型:顺序or并发等等相关配置,不管什么样的消费者类型涉及的配置都会检查)

2、从订阅信息将topic及tag所有遍历出来,构建SubscriptionData放入负载均衡实现类内

3、判断消息模型,广播不处理,集群:增加重试topic(%RETRY%消费组名字)相关订阅信息

4、初始化MQClientInstance

5、RebalanceImpl(负载均衡)类实例相应设置(消费组、消费模型、分配消息队列策略、MQClientInstance)

6、构建消费进度存储对象:广播:本地文件消费进度;集群:远程broker消费进度

7、加载消费进度,广播:加载处理,集群:不处理

8、顺序or并发初始化相应消息消费服务并启动

9、消费者注册到MQClientInstance并启动MQClientInstance

10、远程客户端通信启动

11、MQClientInstance启动时会启动相关定时任务

  • 定时获取name server地址(两分钟)

  • 定时从name server更新topic路由信息(选举namer server的时间间隔)

  • 清除下线的broker及发送心跳到所有的broker(与broker的心跳时间)

  • 持久化所有的消费进度(持久化消费进度的间隔时间)

  • 定时调整线程池(1分钟)

12、拉消息服务启动(一个自旋线程,不停的pull消息)

13、负载均衡服务启动

14、生产者启动(消费者也需要这个,内部使用(TBW102,PRODUCER_INNER_GROUP)

15、当订阅信息改变更新订阅信息

16、发送心跳给所有的broker

17、负载均衡服务线程唤醒

7. 负载均衡队列平均分配算法

以下计算针对一个具体的topic

1、消费端索引计算:当前消费端在所有消息端的索引

2、求模:队列数%消费端数

3、平均大小:队列数是否不大于于消费端数,是:1,不是:(模>0并且索引<模,是:队列数除以消费端数并加1,不是:队列数除以消费端数)

4、开始索引:模>0并且索引<模,是:索引*平均大小,不是:索引乘以平均大小再加模

5、队列范围:平均大小与(队列总数送去开始索引)的最小值

8. 负载均衡的结果

负载均衡根据分配算法(有多个分配算法,平均分配只是其中这一),会将指定范围的消息队列分配给消费端,比如只有一个消费端,那它就会获得所有队列,4个消费队列,2个消费端,每个消费端会消费其中的两个队列(不交叉),另外,非当前topic的队列不会被这些消费端给消费。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不识君的荒漠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值