對于一個消息隊列集群來說,系統(tǒng)由很多臺機器組成癣诱,每個機器的角色计维、IP 地址都不相同,而且這些信息是變動的撕予。這種情況下鲫惶, 如果一個新的Producer 或Consumer 加入,怎么配置連接信息呢嗅蔬?NameServer 的存在主要是為了解決這類問題剑按,由NameServer 維護這些配置信息疾就、狀態(tài)信息澜术,其他角色都通過NameServer 來協(xié)同執(zhí)行。
4.1 NameServer 的功能
NameServer 是整個消息隊列中的狀態(tài)服務(wù)器猬腰,集群的各個組件通過它來了解全局的信息鸟废。同時,各個角色的機器都要定期向NameServer 上報自己的狀態(tài)姑荷,超時不上報的話盒延, NameServer 會認為某個機器出故障不可用了,其他的組件會把這個機器從可用列表里移除鼠冕。
NamServer 可以部署多個添寺,相互之間獨立,其他角色同時向多個NameServer機器上報狀態(tài)信息懈费,從而達到熱備份的目的计露。NameServer 本身是無狀態(tài)的,也就是說NameServer 中的Broker 憎乙、Topic 等狀態(tài)信息不會持久存儲票罐,都是由各個角色定時上報并存儲到內(nèi)存中的( NameServer 支持配置參數(shù)的持久化,一般用不到) 艳丛。
4.1.1 集群狀態(tài)的存儲結(jié)構(gòu)
在org.apache.rocketmq.namesrv.routeinfo 的Rou telnfoManager 類中鞋诗,有五個變量伙判,集群的狀態(tài)就保存在這五個變量中。
4.1.2 狀態(tài)維護邏輯
本節(jié)基于源碼分析NameServer 如何維護各個Broker 的實時狀態(tài)蚕礼,如何根據(jù)Broker 的情況更新各種集群的屬性數(shù)據(jù)。因為其他角色會主動向Name Server 上報狀態(tài)梢什,所以NameServer 的主要邏輯在DefaultRequest Processor類中奠蹬,根據(jù)上報消息里的請求碼做相應(yīng)的處理, 更新存儲的對應(yīng)信息绳矩。
當(dāng)NameServer 和Broker 的長連接斷掉以后罩润, onChannelDestroy 函數(shù)會被調(diào)用,把這個Broker 的信息清理出去翼馆。
NameServer 還有定時檢查時間戳的邏輯割以, Broker 向NameServer發(fā)送的心跳會更新時間戳金度, 當(dāng)NameServer 檢查到時間戳長時間沒有更新后,便會觸發(fā)清理邏輯严沥。從代碼可以看出是每10 秒檢查一次猜极,時間戳超過2 分鐘則認為Broker 已失效。
4.2 各個角色間的交互流程
下面從Topic 的創(chuàng)建入手消玄,結(jié)合源碼分析一下NameServer 如何和其他各個組件交互跟伏,以及NameServer 存儲的元數(shù)據(jù)內(nèi)容的具體含義。
4.2.1 交互流程源碼分析
這里是一堆代碼翩瓜,不貼出了受扳,說下大概意思。
Topic的創(chuàng)建需要指定b和c兩個參數(shù)兔跌,而且他們倆只有一個會起作用( -b 優(yōu)先)勘高, b 參數(shù)指定在哪個Broker 上創(chuàng)建本Topic 的Message Queue , c 參數(shù)表示在這個Cluster 下面所有的Master Broker 上創(chuàng)建這個Topic 的Message Queue , 從而達到高可用性的目的坟桅。具體的創(chuàng)建動作是通過發(fā)送命令觸發(fā)的华望。
在Nameserv執(zhí)行創(chuàng)建Topic的命令后,命令會被發(fā)送到對應(yīng)的Broker上仅乓,Broker 接到創(chuàng)建Topic 的請求后赖舟,執(zhí)行具體的創(chuàng)建邏輯。其中最后一步是向NameServer 發(fā)送注冊信息夸楣, NameServer 完成創(chuàng)建Topic 的邏輯后宾抓,其他客戶端才能發(fā)現(xiàn)新增的Topic。
4.2.2 為何不用ZooKeeper
ZooKeeper 是Apache 的一個開源軟件裕偿,為分布式應(yīng)用程序提供協(xié)調(diào)服務(wù)洞慎。那為什么RocketMQ 要自己造輪子,開發(fā)集群的管理程序呢嘿棘?答案是ZooKeeper 的功能很強大劲腿,包括自動Master選舉等, RocketMQ 的架構(gòu)設(shè)計決定了它不需要進行Master 選舉鸟妙,用不到這些復(fù)雜的功能焦人,只需要一個輕量級的元數(shù)據(jù)服務(wù)器就足夠了。
中間件對穩(wěn)定性要求很高重父, RocketMQ 的NameServer 只有很少的代碼花椭,容易維護,所以不需要再依賴另一個中間件房午,從而減少整體維護成本矿辽。
4.3 底層通信機制
分布式系統(tǒng)各個角色間的通信效率很關(guān)鍵,通信效率的高低直接影響系統(tǒng)性能,基于Socket 實現(xiàn)一個高效的TCP 通信協(xié)議是很有挑戰(zhàn)的袋倔,本節(jié)介紹RocketMQ 是如何解決這個問題的雕蔽。
好吧,這里基本都是代碼宾娜,不介紹了批狐。
4.4 本章小結(jié)
本章介紹了NameServer 的功能, NameServer 在RocketMQ 集群中扮演調(diào)度中心的角色前塔。各個Producer 嚣艇、Consumer 上報自己的狀態(tài)上去,同時從Name Server 獲取其他角色的狀態(tài)信息华弓。NameServer 的功能雖然非常重要食零,但是被設(shè)計得很輕量級,代碼量少并且?guī)缀鯚o磁盤存儲该抒,所有的功能都通過內(nèi)存高效完成慌洪。本章還介紹了底層的通信機制, RocketMQ 基于Netty 對底層通信做了很好的抽象凑保,使得通信功能邏輯清晰,代碼簡單涌攻。Netty 的介紹和具體的通信實現(xiàn)可以查看第13 章欧引。