RocketMq的部署方式
NameServer集群
提供輕量級的服務(wù)發(fā)現(xiàn)和路由定鸟。每個(gè)NameServer?記錄完整的路由信息抡谐,提供等效的讀寫服務(wù)薇芝,并支持快速存儲(chǔ)擴(kuò)展。
就是一個(gè)注冊中心瘪板,存儲(chǔ)當(dāng)前集群所有Brokers信息、Topic跟Broker的對應(yīng)關(guān)系逸吵。
Namesrv用于存儲(chǔ)Topic宛乃、Broker關(guān)系信息,功能簡單峭沦,穩(wěn)定性高贾虽。多個(gè)Namesrv之間相互沒有通信,單臺(tái)Namesrv宕機(jī)不影響其他Namesrv與集群吼鱼;即使整個(gè)Namesrv集群宕機(jī)蓬豁,已經(jīng)正常工作的Producer,Consumer菇肃,Broker仍然能正常工作地粪,但新起的Producer,Consumer,Broker就無法工作琐谤。
Namesrv壓力不會(huì)太大蟆技,平時(shí)主要開銷是在維持心跳和提供Topic-Broker的關(guān)系數(shù)據(jù)。但有一點(diǎn)需要注意斗忌,Broker向Namesr發(fā)心跳時(shí)质礼,會(huì)帶上當(dāng)前自己所負(fù)責(zé)的所有Topic信息,如果Topic個(gè)數(shù)太多(萬級別)织阳,會(huì)導(dǎo)致一次心跳中眶蕉,就Topic的數(shù)據(jù)就幾十M,網(wǎng)絡(luò)情況差的話陈哑,網(wǎng)絡(luò)傳輸失敗妻坝,心跳失敗伸眶,導(dǎo)致Namesrv誤認(rèn)為Broker心跳失敗。
producer集群
生產(chǎn)者刽宪,產(chǎn)生消息的實(shí)例厘贼,擁有相同Producer Group?的Producer?組成一個(gè)集群。
Producer與Name Server集群中的其中一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)建立長連接圣拄,定期從Name Server取Topic路由信息嘴秸,并向提供Topic服務(wù)的Master建立長連接,且定時(shí)向Master發(fā)送心跳庇谆。Producer完全無狀態(tài)岳掐,可集群部署。
Producer Group
用來表示一個(gè)發(fā)送消息應(yīng)用饭耳,一個(gè)Producer Group下包含多個(gè)Producer實(shí)例串述,可以是多臺(tái)機(jī)器,也可以是一臺(tái)機(jī)器的多個(gè)進(jìn)程寞肖,或者一個(gè)進(jìn)程的多個(gè)Producer對象纲酗。一個(gè)Producer Group可以發(fā)送多個(gè)Topic消息,Producer Group作用如下:
? 標(biāo)識(shí)一類Producer
? 可以通過運(yùn)維工具查詢這個(gè)發(fā)送消息應(yīng)用下有多個(gè)Producer實(shí)例
? 發(fā)送分布式事務(wù)消息時(shí)新蟆,如果Producer中途意外宕機(jī)觅赊,Broker會(huì)主動(dòng)回調(diào)Producer Group內(nèi)的任意一臺(tái)機(jī)器來確認(rèn)事務(wù)狀態(tài)。
consumer集群
消息消費(fèi)者琼稻,簡單來說吮螺,消費(fèi)MQ?上的消息的應(yīng)用程序就是消費(fèi)者,至于消息是否進(jìn)行邏輯處理帕翻,還是直接存儲(chǔ)到數(shù)據(jù)庫等取決于業(yè)務(wù)需要鸠补。擁有相同Consumer Group?的
Consumer?組成一個(gè)集群。
Consumer與Name Server集群中的其中一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)建立長連接熊咽,定期從Name Server取Topic路由信息莫鸭,并向提供Topic服務(wù)的Master、Slave建立長連接横殴,且定時(shí)向Master被因、Slave發(fā)送心跳。Consumer既可以從Master訂閱消息衫仑,也可以從Slave訂閱消息梨与,訂閱規(guī)則由Broker配置決定。
Consumer Group
用來表示一個(gè)消費(fèi)消息應(yīng)用文狱,一個(gè)Consumer Group下包含多個(gè)Consumer實(shí)例粥鞋,可以是多臺(tái)機(jī)器,也可以是多個(gè)進(jìn)程瞄崇,或者是一個(gè)進(jìn)程的多個(gè)Consumer對象呻粹。一個(gè)Consumer Group下的多個(gè)Consumer以均攤方式消費(fèi)消息壕曼,如果設(shè)置為廣播方式,那么這個(gè)Consumer Group下的每個(gè)實(shí)例都消費(fèi)全量數(shù)據(jù)等浊。
broker集群
通過提供輕量級的Topic?和Queue?機(jī)制來處理消息存儲(chǔ),同時(shí)支持推(push)和拉(pull)模式以及主從結(jié)構(gòu)的容錯(cuò)機(jī)制腮郊。
集群最核心模塊,主要負(fù)責(zé)Topic消息存儲(chǔ)筹燕、管理和分發(fā)等功能轧飞。
單個(gè)Broker跟所有Namesrv保持心跳請求,心跳間隔為30秒撒踪,心跳請求中包括當(dāng)前Broker所有的Topic信息过咬。Namesrv會(huì)反查Broer的心跳信息,如果某個(gè)Broker在2分鐘之內(nèi)都沒有心跳制妄,則認(rèn)為該Broker下線掸绞,調(diào)整Topic跟Broker的對應(yīng)關(guān)系。但此時(shí)Namesrv不會(huì)主動(dòng)通知Producer忍捡、Consumer有Broker宕機(jī)集漾。
Broker部署相對復(fù)雜,Broker分為Master與Slave砸脊,一個(gè)Master可以對應(yīng)多個(gè)Slave,但是一個(gè)Slave只能對應(yīng)一個(gè)Master纬霞,Master與Slave的對應(yīng)關(guān)系通過指定相同的BrokerName凌埂,不同的BrokerId來定義,BrokerId為0表示Master诗芜,非0表示Slave瞳抓。Master也可以部署多個(gè)。每個(gè)Broker與Name Server集群中的所有節(jié)點(diǎn)建立長連接伏恐,定時(shí)注冊Topic信息到所有Name Server孩哑。
消息發(fā)送
producer的消息發(fā)送流程;
? 所有producer的send()方法都調(diào)用了defaultMqProducer.send()方法翠桦;
? 這也是為什么我們需要對每一個(gè)pdoducer進(jìn)行配置的原因横蜒;
生產(chǎn)者發(fā)送時(shí),會(huì)自動(dòng)輪詢當(dāng)前所有可發(fā)送的broker销凑,一條消息發(fā)送成功丛晌,下次換另外一個(gè)broker發(fā)送,以達(dá)到消息平均落到所有的broker上斗幼。
這里需要注意一點(diǎn):假如某個(gè)Broker宕機(jī)澎蛛,意味生產(chǎn)者最長需要30秒才能感知到。在這期間會(huì)向宕機(jī)的Broker發(fā)送消息蜕窿。當(dāng)一條消息發(fā)送到某個(gè)Broker失敗后谋逻,會(huì)往該broker自動(dòng)再重發(fā)呆馁,假如還是發(fā)送失敗,則拋出發(fā)送失敗異常毁兆。業(yè)務(wù)捕獲異常浙滤,重新發(fā)送即可。
TopicPublishInfo類是用于producer端做負(fù)載均衡的關(guān)鍵類荧恍,producer通過這個(gè)類來識(shí)別broker并選擇broker瓷叫;
MessageQueue類:
描述了單個(gè)消息隊(duì)列的模型;
? 這個(gè)隊(duì)列用于管理哪個(gè)topic以及這個(gè)隊(duì)列在哪個(gè)broker里
TopicRouteData類:
Topic路由信息集中管理了當(dāng)前topic下的所有隊(duì)列信息和broker信息送巡;
? brokerdata中包含了該broker的brokerGroup名字和物理地址摹菠;
producer的負(fù)載均衡
producer的負(fù)載均衡由MQFaultStratage.selectOneMessageQueue()實(shí)現(xiàn)
MQFaultStratage這個(gè)類是MQ負(fù)載均衡的核心類
這個(gè)類描述了MQ負(fù)載均衡的策略
如何選擇一個(gè)broker達(dá)到負(fù)載均衡
? 1.盡量不要選擇剛剛選擇過的broker
? 2.不要選擇延遲容錯(cuò)內(nèi)的broker
隨機(jī)選擇broker
producer每次在使用broker的時(shí)候會(huì)記錄這次使用的是哪個(gè)broker;下次在選取broker的時(shí)候主動(dòng)排除這個(gè)broker骗爆;
? 在未推送任何消息時(shí)次氨,producer中的mq為空,此時(shí)lastBrokerName也為空摘投;
? 選擇broker是負(fù)載均衡的關(guān)鍵煮寡,基于方法selectOneMessageQueue(),這個(gè)方法會(huì)隨機(jī)選擇一個(gè)broker;
避開上次選取的broker
當(dāng)延遲容錯(cuò)未開啟時(shí)
延遲容錯(cuò)下選擇broker
遍歷所有broker直至找到一個(gè)broker可用(不在延遲容錯(cuò)里或已經(jīng)可以從延遲容錯(cuò)里去除)犀呼;如果所有broker都不可用則隨機(jī)選取一個(gè)幸撕;
consumer的負(fù)載均衡
consumer在啟動(dòng)的時(shí)候會(huì)實(shí)例化rebalanceImpl,這個(gè)類負(fù)責(zé)消費(fèi)端的負(fù)載均衡
MqClientInstance里會(huì)調(diào)用doRebalance()來進(jìn)行負(fù)載均衡外臂;
? consumer負(fù)載均衡是指將topicMessageQueue中的消息隊(duì)列分配到消費(fèi)者組的具體消費(fèi)者里去坐儿;
? consumer的負(fù)載均衡由rebalanceImpl調(diào)用allocateMesasgeQueueStratage.allocate()完成;
? 每次有新的consumer加入group就會(huì)重新做一下負(fù)載宋光;
? 每10秒自動(dòng)做一次負(fù)載貌矿;
allocateMesasgeQueueStratage.allocate()
consumer負(fù)載均衡有6種模式:
? 分頁模式(隨機(jī)分配模式)
? 手動(dòng)配置模式
? 指定機(jī)房模式
? 就近機(jī)房模式
? 統(tǒng)一哈希模式
? 環(huán)型模式