代碼:
安裝:
幾個配置文件。
---12-13---
源碼:
第一步:
解析參數填充屬性。
這裏主要是創建config
這個就是配置心跳路由什麼的配置的。
這個Bytebuffer是堆外的緩衝區。
端口設置爲9876。
啓動流程的第一步完畢。new一個Controller。
把屬性給nameServerController。
---14-15--
進入:
啓動的第二步:
進入:
這個方法主要做了什麼?
---16---
啓動的第三步:
啓動之前如果報錯的話,鉤子方法進行資源的釋放。
---17---
第一個:topicQueueTableTopic消息隊列路由信息,消息發送時根據路由表進行負載均衡
都二個:brokerAddrTable存的是brokert的基本信息,包括brokerName、所屬集羣名稱、主備Broker地址
第三個: clusterAddrTable存的是broker的集羣信息,集羣所有的broker的名稱
第四個:brokerLiveTable存的是broker的狀態信息,NameServer每次收到心跳包都會替換該信息
第五個:FilterServer
---18---
看下路由的註冊:
進入createBrokerController
進入這個方法可知:
對於生產者來說broker處理生產者的請求就作爲生產者的服務端進行設置的。
對於nameserver則是netty的客戶端。
這裏看出通過10911這個端口提交信息。
接下來我們填充配置類,看下屬性的信息是在哪裏來的。
這個去c裏面讀的話讀的是什麼?
看下一個很重要的代碼:
這個就是nameServer的地址。
往下就是一直在填充配置類了。
再往下:
這裏就是創建了brokerController,然後初始化,我們點到初始化的配置中去。
其實就是完成broker屬性本身的一個賦值操作。
在往下
面試點,啓動的時候優雅停機,小細節我們在說下:
接下來就是start方法了。
前面的都不用管,我麼們就是註冊路由信息就可以了。
創建了一個定時的線程池,這裏就是每隔30s註冊信息。
進去註冊的方法,這裏是synchronized:
繼續調用
分別給每一個nameServer註冊broker的信息:
---19---
我們在nameServer再看下:
很多的請求是請求的nameServer的,我們找下:
核心的註冊:
再進入:
進入也是加鎖的:
寫鎖說明註冊是串行的。
看下版本:
---20---
路由刪除:
以nameServer定期掃描來看:
這裏:
這個是怎麼弄的呢?就是遍歷所有的+120S還是小於就是down機。
關閉,移除。
維護其他的路由表。也是枷鎖的同步的。
隊列爲空就移除主題。
---21---
路由的發現,需要客戶端主動的拉取,nameServer提供一個方法。
我們看下這個類,這個類是專門處理客戶端的請求的:
這個就是根據主題獲得路由信息。
這裏摘取相關的信息。
填充topicRouteData。
讀鎖。
---22---
看下類的關係圖:
啓動
開始就實例化了:
---
就是拿到客戶端的實例,把生產者放在實例裏面去。
---23---24--
消息的發送:
最終調用的是這個方法:
---25---
路由的查找:目的是根據主題找broker。
先去本地緩存查找:
沒有的話去nameServer中查找:
進入:
請求nameServer獲得主題的路由信息,再次點擊進入:
和本地緩存的路由表比較更新:
再來放在這裏:
---26---
選擇隊列:
傳入兩個參數就是路由信息和lastBrokerName,第二個參數主要是做負載均衡的。
輪詢的給不同的隊列去發。
如果lastBrokerName爲空就直接調用。
---
有延時機制的話:
首先是校驗是不是合法的
如果在維護的表裏面找到的是不可用的話。
---27---
消息的發送:
看下源碼的這個方法有註釋。
---28---
小結。
---29---
批量消息發送:
對批量消息整個設置topic。
---30---
消息存貯的源碼。
---31---
入口。
首先是追加到內存,然後追加到磁盤中。
slave是不能put的。
往下翻,進入這個:
進入:
前面是一堆驗證,後面進去消息的追加:
進入doAppend方法:
刷盤:
往下:
---32---
消息存儲文件的介紹:
:主題爲文件夾的名字每一個文件夾存名字,
存儲了每一個消息隊列。
---33---
存儲文件的內存映射:
內存映射的一些重要的類,當作commitLog下面的目錄本身就可以了:
---34---
MappedFile就是commitLog的目錄下的每一個文件。
看下MappedFile這個類。
看下初始化的方法:
我們看一個屬性:
這個屬性就是
---35---
看文檔
---36---
進去:
start本質上調用的是run方法。
我們看下run方法,每隔1ms執行數據的分發:
找到消息,其實是很多的消息。
分發是分發到兩個地方的:
這個是兩個實現一個是給consumerQueue分發的一個是給index分發的
---37---
看下更新到cosumerQueue的基本流程。
往下看最核心的代碼:
進去:
---38---
IndexFile文件的轉發。
進入buildIndex方法 。
---39---
消息隊列的索引文件的恢復:
先存儲到commitlog中然乎異步的更新到consumerqueue和indexFile中。
看下這個方法,把這些文件都加載了一遍了。
開始進行文件的恢復:
走文件的恢復:
---40---
看下正常恢復的機制:
---41---
rocketmq的刷盤機制。
我們看下消息追加的入口:
內存映射詳解:https://www.bilibili.com/video/BV1dt41147JS?from=search&seid=5974336792410216241
同步刷盤:
看下提交是怎麼做的?
這個類看一下。
---42---
異步刷盤。
這兩個類是很重要的。
---43---
過期文件的刪除機制:
---44---
小結
---45---
---46---47---
...
---48---
消息的拉取。
看下run方法:
看下如何處理拉取的請求的。
再進去:
pullRequest:
---49---
隨着MQClieneInstance啓動而啓動的,要調用run方法的。
我們看下pullMessage方法:
---50---
broker去組裝消息:
看這個類
這個方法:
---51---
消息的客戶端處理服務端的響應:
客戶端處理的入口:
繼續跟進去:
繼續跟進去:
繼續跟進:
看着裏面的pullCallback
當前的消息拿出來放在processQueue中。
---52---
消息拉取的流程小結:
---53---
消息拉取的長輪詢機制分析:
我們看下代碼:
放在隊列裏面其實就是等待喚醒機制的。
這個是一個服務,它其實有一個線程的,看下它的run方法。
長輪詢的入口:
---54---
開啓了長輪詢的話就是每隔5s檢查的。
start()執行之後會執行run方法。‘
進入doReput
往下走:
進入:
往下:
---55---
消息隊列重新負載:
負載是隨着MQClientInstance的啓動二啓動的。
點進去:
再進去:
負載均衡的策略:
---56---
消息消費:
看下消息處理的過程:
進入這個類的run方法:
入口在哪裏:
---57---
定時消息的處理機制:
進去:
看源碼。
---58---
順序消息,每隔20s
---59---