RocketMQ源码分析之路由

RocketMQ源码分析我们主要从NameSrv、路由、生产者、消费者、消息存储等方面一点点分析,本章主要讲的是路由相关的源码分析。

一、路由元信息

NameSrv中存储了topic的路由信息,这样跟生产者、消费者交互的时候,为两者提供topic的路由信息,NameSrv还得存储路由信息,还得管理节点,包括路由的注册和路由的清除。

路由信息主要在RouteInfoManager类中,其中主要包括以下几个HashMap,用来存储不同的信息。

topicQueueTable:Topic消息队列路由信息,主要记录了该topic存储在哪些broker中,NameSrv收到消息时会根据该路由表进行负载均衡。

brokerAddrTable:broker基础路由信息,主要包含broker名称、集群名称等;

clusterAddrTable:broker集群的路由信息,只包含集群中broker的名字;

brokerLiveTable:broker状态的路由信息,包含每个broker最后一次发送心跳的时间等,broker每次发送心跳包到NameSrv,该信息就会被更新;

filterServerTable:broker上的消息过滤等路由信息。

二、路由的注册

路由的注册涉及两方面,一个是broker端进行路由注册的请求,一个是namesrv端对路由注册请求的处理。

1、broker端路由注册的请求

BrokerStartup的启动类:org.apache.rocketmq.broker.BrokerStartup。

BrokerStartup的main()方法中调用start(createBrokerController(args)),先创建BrokerController再调用BrokerController的start()方法。

createBrokerController包含了三个步骤:创建BrokerController、实例化BrokerController、销毁BrokerController。

1.1、BrokerController的创建、实例化、销毁

创建BrokerController跟创建NameSrvController差不多,都是创建配置文件读取类、根据配置参数不同,读取不同的配置文件。

BrokerConfig是Broker配置文件类,不多说。

跟NameSrvController不同的是这里多了一个NettyClientConfig配置类,主要是broker要接收生产者的消息,这时是netty的服务端,而又要跟namesrv发送心跳包,因此又是netty的客户端。

跟NameSrvController一样-c以后跟的是配置文件的路径,读取了以后用来填充配置文件类。

 BrokerController的实例化,调用controller的initialize方法,里面实例化不细说了,后面其他模块会细说的。

BrokerController的销毁,还是一样,在jvm中注册钩子函数,当jvm退出的时候调用钩子函数的run方法对资源进行释放。

1.2、路由注册的请求

路由注册的请求其实还是调用BrokerController的start()方法。

通过BrokerController的start()方法,可以看到调用了BrokerController的registerBrokerAll()方法,将broker相关信息都注册到namesrv。至于下面的定时线程任务,可以看到延迟十秒,然后每三十秒重新向namesrv注册一下自己,其实也就是每三十秒发送一次心跳。

我们再仔细看registerBrokerAll()方法,registerBrokerAll()方法调用了doRegisterBrokerAll()方法

doRegisterBrokerAll()方法调用了brokerOuterAPI的registerBrokerAll()方法

 

然后发现registerBrokerAll()方法中用线程池去注册

 然后发现注册方法中有一个oneway的发送方式,就是直接发送心跳包,没有反馈的,默认不使用这个模式的。然后还有一个调用remotingClient的invokeSync同步注册方法

remotingClient其实就是一个netty客户端的实例,通过netty跟namesrv通信。

 

2、namesrv处理路由注册的请求

处理路由注册的请求是namesrv端的工作,相信大家都能理解。处理该请求的类org.apache.rocketmq.namesrv.processor下的DefaultRequestProcessor类中。处理方法是DefaultRequestProcessor的processRequest()方法。该方法中拿到请求code以后,通过code进行判断请求是什么请求。

其实调用的就是RouteInfoManager的registerBroker()方法

在registerBroker()方法中就能看到往brokerAddrTable、clusterAddrTable、brokerLiveTable中添加数据。这几个hashmap,是不是很熟悉,咱们介绍路由元信息的时候,是不是介绍过这几个,这几个存储的就是broker的路由元信息。

到此,路由的注册以及对应的处理都清楚了吧。broker通过netty的客户端发送路由的信息心跳包到namesrv,namesrv收到信息以后解析然后存储。

三、路由的删除

路由的删除包括两方面,一个是NamesrvController实例化的时候启动了一个定时线程任务扫描最近一次上报时间与当前时间相差两分钟以及以上的broker,然后删除。另一个是broker关闭的时候自动向namesrv发送删除路由信息的请求。

一个是NamesrvController中initialize()中使用线程扫描,然后最后一次上报时间到现在大于两分钟的,清除其路由相关的信息,

topicQueueTable、brokerAddrTable、clusterAddrTable、brokerLiveTable、filterServerTable等。

另一个是broker端BrokerStartup的shutdown()方法,就是用netty给namesrv发送了一个UNREGISTER_BROKER请求,然后namesrv收到以后进行处理,这里就不细说了,处理跟上面一样。都是移除路由相关的那几个hashmap里的信息,可以自己看一下。

 

四、路由的发现

路由的发现,其实就是namesrv上的路由信息发生了改变,但是不会主动去将变动推送给Producer,而是客服端主动去向namesrv发送请求,主动拉取路由相关信息,因此路由发现不是实时的。

在org.apache.rocketmq.namesrv.processor下的DefaultRequestProcessor中有对获取topic路由请求的处理。

  

RocketMQ是一个开源的分布式消息间件,由阿里巴巴开发,主要用于大规模的消息传输和处理。阅读RocketMQ源码可以帮助你深入了解其内部工作机制、设计模式以及优化策略。以下是阅读RocketMQ源码的一些步骤和关键点: 1. **入门准备**: - 安装必要的依赖:首先需要对Java和相关开发环境(如Maven或Gradle)有一定了解。 - 了解项目结构:熟悉RocketMQ的代码仓库结构,主要包括`mq-client`, `mq-common`, `mq-server`, `mq-externalservice`等主要模块。 2. **理解设计思想**: - 分布式系统设计:研究分区、集群、消息路由、故障恢复机制。 - 消息模型:Consumer Group, Topic, Queue, Orderly Consumers等概念。 - 事务一致性:检查如何处理消息的事务性和持久化。 3. **核心组件**: - **Broker**:查看消息的存储、消费分发、事务管理和高可用性实现。 - **Producer**:了解消息发送流程,包括序列化、路由选择、发送确认机制。 - **Consumer**:研究拉取消费模式和顺序消费的实现。 4. **关键技术实现**: - **Message Queueing(MQ)**:学习如何使用队列来存储和分发消息。 - **Reentrant Locks**:查看并发控制的使用。 - **高可用和容错**:关注心跳检测、主备切换、网络重试策略等。 5. **查阅文档和注释**: - 阅读官方文档、API文档和开发者指南,有助于理解源码各种类和方法的作用。 - 源码的JavaDoc是非常重要的参考资料。 6. **实践与问题跟踪**: - 尝试在本地搭建并运行RocketMQ,通过实际操作发现问题。 - 查阅GitHub上的issue和PR,了解社区对源码的讨论和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值