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路由請求的處理。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章