本篇內(nèi)容介紹了“RocketMQ中的autoCreateTopicEnable為什么不能設(shè)置為true”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)公司推出扶綏免費(fèi)做網(wǎng)站回饋大家。
很多網(wǎng)友會(huì)問(wèn),為什么明明集群中有多臺(tái)Broker服務(wù)器,autoCreateTopicEnable設(shè)置為true,表示開(kāi)啟Topic自動(dòng)創(chuàng)建,但新創(chuàng)建的Topic的路由信息只包含在其中一臺(tái)Broker服務(wù)器上,這是為什么呢?
期望值:為了消息發(fā)送的高可用,希望新創(chuàng)建的Topic在集群中的每臺(tái)Broker上創(chuàng)建對(duì)應(yīng)的隊(duì)列,避免Broker的單節(jié)點(diǎn)故障。
現(xiàn)象截圖如下:
正如上圖所示,自動(dòng)創(chuàng)建的topicTest5的路由信息:
topicTest5只在broker-a服務(wù)器上創(chuàng)建了隊(duì)列,并沒(méi)有在broker-b服務(wù)器創(chuàng)建隊(duì)列,不符合期望。
默認(rèn)讀寫隊(duì)列的個(gè)數(shù)為4。
我們?cè)賮?lái)看一下RocketMQ默認(rèn)topic的路由信息截圖如下:
從圖中可以默認(rèn)Topic的路由信息為broker-a、broker-b上各8個(gè)隊(duì)列。
默認(rèn)Topic的路由信息是如何創(chuàng)建的?
Topic的路由信息是存儲(chǔ)在哪里?Nameserver?broker?
RocketMQ Topic默認(rèn)隊(duì)列個(gè)數(shù)是多少呢?
Broker在啟動(dòng)時(shí)向Nameserver注冊(cè)存儲(chǔ)在該服務(wù)器上的路由信息,并每隔30s向Nameserver發(fā)送心跳包,并更新路由信息。
Nameserver每隔10s掃描路由表,如果檢測(cè)到Broker服務(wù)宕機(jī),則移除對(duì)應(yīng)的路由信息。
消息生產(chǎn)者每隔30s會(huì)從Nameserver重新拉取Topic的路由信息并更新本地路由表;在消息發(fā)送之前,如果本地路由表中不存在對(duì)應(yīng)主題的路由消息時(shí),會(huì)主動(dòng)向Nameserver拉取該主題的消息。
回到本文的主題:autoCreateTopicEnable,開(kāi)啟自動(dòng)創(chuàng)建主題,試想一下,如果生產(chǎn)者向一個(gè)不存在的主題發(fā)送消息時(shí),上面的任何一個(gè)步驟都無(wú)法獲取一個(gè)不存在的主題的路由信息,那該如何處理這種情況呢?
在RocketMQ中,如果autoCreateTopicEnable設(shè)置為true,消息發(fā)送者向NameServer查詢主題的路由消息返回空時(shí),會(huì)嘗試用一個(gè)系統(tǒng)默認(rèn)的主題名稱(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC),此時(shí)消息發(fā)送者得到的路由信息為:
但問(wèn)題就來(lái)了,默認(rèn)Topic在集群的每一臺(tái)Broker上創(chuàng)建8個(gè)隊(duì)列,那問(wèn)題來(lái)了,為啥新創(chuàng)建的Topic只在一個(gè)Broker上創(chuàng)建4個(gè)隊(duì)列?
溫馨提示:本文不會(huì)詳細(xì)跟蹤整個(gè)創(chuàng)建過(guò)程,只會(huì)點(diǎn)出源碼的關(guān)鍵入口點(diǎn),如想詳細(xì)了解NameServer路由消息、消息發(fā)送高可用的實(shí)現(xiàn)原理,建議查閱筆者的書(shū)籍《RocketMQ技術(shù)內(nèi)幕》第二、三章。
Step1:在Broker啟動(dòng)流程中,會(huì)構(gòu)建TopicConfigManager對(duì)象,其構(gòu)造方法中首先會(huì)判斷是否開(kāi)啟了允許自動(dòng)創(chuàng)建主題,如果啟用了自動(dòng)創(chuàng)建主題,則向topicConfigTable中添加默認(rèn)主題的路由信息。 TopicConfigManager構(gòu)造方法
備注:該topicConfigTable中所有的路由信息,會(huì)隨著B(niǎo)roker向Nameserver發(fā)送心跳包中,Nameserver收到這些信息后,更新對(duì)應(yīng)Topic的路由信息表。
BrokerConfig的defaultTopicQueueNum默認(rèn)為8。兩臺(tái)Broker服務(wù)器都會(huì)運(yùn)行上面的過(guò)程,故最終Nameserver中關(guān)于默認(rèn)主題的路由信息中,會(huì)包含兩個(gè)Broker分別各8個(gè)隊(duì)列信息。
Step2:生產(chǎn)者尋找路由信息 生產(chǎn)者首先向NameServer查詢路由信息,由于是一個(gè)不存在的主題,故此時(shí)返回的路由信息為空,RocketMQ會(huì)使用默認(rèn)的主題再次尋找,由于開(kāi)啟了自動(dòng)創(chuàng)建路由信息,NameServer會(huì)向生產(chǎn)者返回默認(rèn)主題的路由信息。然后從返回的路由信息中選擇一個(gè)隊(duì)列(默認(rèn)輪詢)。消息發(fā)送者從Nameserver獲取到默認(rèn)的Topic的隊(duì)列信息后,隊(duì)列的個(gè)數(shù)會(huì)改變嗎?答案是會(huì)的,其代碼如下:
MQClientInstance#updateTopicRouteInfoFromNameServer
溫馨提示:消息發(fā)送者在到默認(rèn)路由信息時(shí),其隊(duì)列數(shù)量,會(huì)選擇DefaultMQProducer#defaultTopicQueueNums與Nameserver返回的的隊(duì)列數(shù)取最小值,DefaultMQProducer#defaultTopicQueueNums默認(rèn)值為4,故自動(dòng)創(chuàng)建的主題,其隊(duì)列數(shù)量默認(rèn)為4。
Step3:發(fā)送消息
DefaultMQProducerImpl#sendKernelImpl
在消息發(fā)送時(shí)的請(qǐng)求報(bào)文中,設(shè)置默認(rèn)topic名稱,消息發(fā)送topic名稱,使用的隊(duì)列數(shù)量為DefaultMQProducer#defaultTopicQueueNums,即默認(rèn)為4。
Step4:Broker端收到消息后的處理流程 服務(wù)端收到消息發(fā)送的處理器為:SendMessageProcessor,在處理消息發(fā)送時(shí),會(huì)調(diào)用super.msgCheck方法: AbstractSendMessageProcessor#msgCheck
在Broker端,首先會(huì)使用TopicConfigManager根據(jù)topic查詢路由信息,如果Broker端不存在該主題的路由配置(路由信息),此時(shí)如果Broker中存在默認(rèn)主題的路由配置信息,則根據(jù)消息發(fā)送請(qǐng)求中的隊(duì)列數(shù)量,在Broker創(chuàng)建新Topic的路由信息。這樣Broker服務(wù)端就會(huì)存在主題的路由信息。
在Broker端的topic配置管理器中存在的路由信息,一會(huì)向Nameserver發(fā)送心跳包,匯報(bào)到Nameserver,另一方面會(huì)有一個(gè)定時(shí)任務(wù),定時(shí)存儲(chǔ)在broker端,具體路徑為${ROCKET_HOME}/store/config/topics.json中,這樣在Broker關(guān)閉后再重啟,并不會(huì)丟失路由信息。
廣大讀者朋友,跟蹤到這一步的時(shí)候,大家應(yīng)該對(duì)啟用自動(dòng)創(chuàng)建主題機(jī)制時(shí),新主題是的路由信息是如何創(chuàng)建的,為了方便理解,給出創(chuàng)建主題序列圖:
經(jīng)過(guò)上面自動(dòng)創(chuàng)建路由機(jī)制的創(chuàng)建流程,我們可以比較容易的分析得出如下結(jié)論: 因?yàn)殚_(kāi)啟了自動(dòng)創(chuàng)建路由信息,消息發(fā)送者根據(jù)Topic去NameServer無(wú)法得到路由信息,但接下來(lái)根據(jù)默認(rèn)Topic從NameServer是能拿到路由信息(在每個(gè)Broker中,存在8個(gè)隊(duì)列),因?yàn)閮蓚€(gè)Broker在啟動(dòng)時(shí)都會(huì)向NameServer匯報(bào)路由信息。此時(shí)消息發(fā)送者緩存的路由信息是2個(gè)Broker,每個(gè)Broker默認(rèn)4個(gè)隊(duì)列(原因見(jiàn)3.2.1:Step2的分析)。消息發(fā)送者然后按照輪詢機(jī)制,發(fā)送第一條消息選擇(broker-a的messageQueue:0),向Broker發(fā)送消息,Broker服務(wù)器在處理消息時(shí),首先會(huì)查看自己的路由配置管理器(TopicConfigManager)中的路由信息,此時(shí)不存在對(duì)應(yīng)的路由信息,然后嘗試查詢是否存在默認(rèn)Topic的路由信息,如果存在,說(shuō)明啟用了autoCreateTopicEnable,則在TopicConfigManager中創(chuàng)建新Topic的路由信息,此時(shí)存在與Broker服務(wù)端的內(nèi)存中,然后本次消息發(fā)送結(jié)束。此時(shí),在NameServer中還不存在新創(chuàng)建的Topic的路由信息。
這里有三個(gè)關(guān)鍵點(diǎn):
啟用autoCreateTopicEnable創(chuàng)建主題時(shí),在Broker端創(chuàng)建主題的時(shí)機(jī)為,消息生產(chǎn)者往Broker端發(fā)送消息時(shí)才會(huì)創(chuàng)建。
然后Broker端會(huì)在一個(gè)心跳包周期內(nèi),將新創(chuàng)建的路由信息發(fā)送到NameServer,于此同時(shí),Broker端還會(huì)有一個(gè)定時(shí)任務(wù),定時(shí)將內(nèi)存中的路由信息,持久化到Broker端的磁盤上。
消息發(fā)送者會(huì)每隔30s向NameServer更新路由信息,如果消息發(fā)送端一段時(shí)間內(nèi)未發(fā)送消息,就不會(huì)有消息發(fā)送集群內(nèi)的第二臺(tái)Broker,那么NameServer中新創(chuàng)建的Topic的路由信息只會(huì)包含Broker-a,然后消息發(fā)送者會(huì)向NameServer拉取最新的路由信息,此時(shí)就會(huì)消息發(fā)送者原本緩存了2個(gè)broker的路由信息,將會(huì)變?yōu)橐粋€(gè)Broker的路由信息,則該Topic的消息永遠(yuǎn)不會(huì)發(fā)送到另外一個(gè)Broker,就出現(xiàn)了上述現(xiàn)象。
原因就分析到這里了,現(xiàn)在我們還可以的大膽假設(shè),開(kāi)啟autoCreateTopicEnable機(jī)制,什么情況會(huì)在兩個(gè)Broker上都創(chuàng)建隊(duì)列,其實(shí),我們只需要連續(xù)快速的發(fā)送9條消息,就有可能在2個(gè)Broker上都創(chuàng)建隊(duì)列,驗(yàn)證代碼如下:
public static void main(String[] args) throws MQClientException, InterruptedException { DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name"); producer.setNamesrvAddr("127.0.0.1:9876"); producer.start(); for (int i = 0; i < 9; i++) { try { Message msg = new Message("TopicTest10" ,"TagA" , ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)); SendResult sendResult = producer.send(msg); System.out.printf("%s%n", sendResult); } catch (Exception e) { e.printStackTrace(); Thread.sleep(1000); } } producer.shutdown(); }
驗(yàn)證結(jié)果如圖所示:
“RocketMQ中的autoCreateTopicEnable為什么不能設(shè)置為true”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
本文標(biāo)題:RocketMQ中的autoCreateTopicEnable為什么不能設(shè)置為true
瀏覽路徑:http://www.rwnh.cn/article26/jjsijg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站維護(hù)、網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、外貿(mào)網(wǎng)站建設(shè)、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)