一愿卒、 RocketMQ概述
1缚去、MQ概述
1)MQ簡介
MQ,Message Queue琼开,是一種提供消息隊列服務(wù)的中間件易结,也稱為消息中間件,是一套提供了消息生 產(chǎn)柜候、存儲搞动、消費全過程API的軟件系統(tǒng)。消息即數(shù)據(jù)渣刷。一般消息的體量不會很大鹦肿。
2)MQ用途
限流削峰
MQ可以將系統(tǒng)的超量請求暫存其中,以便系統(tǒng)后期可以慢慢進行處理辅柴,從而避免了請求的丟失或系統(tǒng) 被壓垮箩溃。
異步解耦
上游系統(tǒng)對下游系統(tǒng)的調(diào)用若為同步調(diào)用高诺,則會大大降低系統(tǒng)的吞吐量與并發(fā)度,且系統(tǒng)耦合度太高碾篡。 而異步調(diào)用則會解決這些問題虱而。所以兩層之間若要實現(xiàn)由同步到異步的轉(zhuǎn)化,一般性做法就是开泽,在這兩 層間添加一個MQ層牡拇。
數(shù)據(jù)收集
分布式系統(tǒng)會產(chǎn)生海量級數(shù)據(jù)流,如:業(yè)務(wù)日志穆律、監(jiān)控數(shù)據(jù)惠呼、用戶行為等。針對這些數(shù)據(jù)流進行實時或 批量采集匯總峦耘,然后對這些數(shù)據(jù)流進行大數(shù)據(jù)分析剔蹋,這是當(dāng)前互聯(lián)網(wǎng)平臺的必備技術(shù)。通過MQ完成此 類數(shù)據(jù)收集是最好的選擇辅髓。
3)常見MQ產(chǎn)品
ActiveMQ
ActiveMQ是使用Java語言開發(fā)一款MQ產(chǎn)品泣崩。早期很多公司與項目中都在使用。但現(xiàn)在的社區(qū)活躍度已 經(jīng)很低÷蹇冢現(xiàn)在的項目中已經(jīng)很少使用了矫付。
RabbitMQ
RabbitMQ是使用ErLang語言開發(fā)的一款MQ產(chǎn)品。其吞吐量較Kafka與RocketMQ要低第焰,且由于其不是 Java語言開發(fā)买优,所以公司內(nèi)部對其實現(xiàn)定制化開發(fā)難度較大。
Kafka
Kafka是使用Scala/Java語言開發(fā)的一款MQ產(chǎn)品挺举。其最大的特點就是高吞吐率杀赢,常用于大數(shù)據(jù)領(lǐng)域的實 時計算、日志采集等場景湘纵。其沒有遵循任何常見的MQ協(xié)議脂崔,而是使用自研協(xié)議。對于Spring Cloud Net?ix瞻佛,其僅支持RabbitMQ與Kafka脱篙。
RocketMQ
RocketMQ是使用Java語言開發(fā)的一款MQ產(chǎn)品。經(jīng)過數(shù)年阿里雙11的考驗伤柄,性能與穩(wěn)定性非常高绊困。其 沒有遵循任何常見的MQ協(xié)議,而是使用自研協(xié)議适刀。對于Spring Cloud Alibaba秤朗,其支持RabbitMQ、 Kafka笔喉,但提倡使用RocketMQ
對比
ACTIVEMQ | RABBITMQ | KAFKA | ROCKETMQ | |
---|---|---|---|---|
開發(fā)語言 | Java | ErLang | Java | Java |
單機吞吐 量 | 萬級 | 萬級 | 十萬級 | 十萬級 |
Topic | - | - | 百級Topic時會影響系統(tǒng)吞吐量 | 千級Topic時會影響系統(tǒng)吞吐 量 |
社區(qū)活躍 度 | 低 | 高 | 高 | 高 |
4)MQ常見協(xié)議
一般情況下MQ的實現(xiàn)是要遵循一些常規(guī)性協(xié)議的取视。常見的協(xié)議如下:
JMS
JMS硝皂,Java Messaging Service(Java消息服務(wù))。是Java平臺上有關(guān)MOM(Message Oriented Middleware作谭,面向消息的中間件 PO/OO/AO)的技術(shù)規(guī)范稽物,它便于消息系統(tǒng)中的Java應(yīng)用程序進行消 息交換,并且通過提供標(biāo)準(zhǔn)的產(chǎn)生折欠、發(fā)送贝或、接收消息的接口,簡化企業(yè)應(yīng)用的開發(fā)锐秦。ActiveMQ是該協(xié) 議的典型實現(xiàn)咪奖。
STOMP
STOMP,Streaming Text Orientated Message Protocol(面向流文本的消息協(xié)議)酱床,是一種MOM設(shè)計 的簡單文本協(xié)議羊赵。STOMP提供一個可互操作的連接格式,允許客戶端與任意STOMP消息代理 (Broker)進行交互扇谣。ActiveMQ是該協(xié)議的典型實現(xiàn)昧捷,RabbitMQ通過插件可以支持該協(xié)議。
AMQP
AMQP揍堕,Advanced Message Queuing Protocol(高級消息隊列協(xié)議)料身,一個提供統(tǒng)一消息服務(wù)的應(yīng)用 層標(biāo)準(zhǔn),是應(yīng)用層協(xié)議的一個開放標(biāo)準(zhǔn)衩茸,是一種MOM設(shè)計≈ⅲ基于此協(xié)議的客戶端與消息中間件可傳遞 消息楞慈,并不受客戶端/中間件不同產(chǎn)品,不同開發(fā)語言等條件的限制啃擦。 RabbitMQ是該協(xié)議的典型實 現(xiàn)囊蓝。
MQTT
MQTT,Message Queuing Telemetry Transport(消息隊列遙測傳輸)令蛉,是IBM開發(fā)的一個即時通訊協(xié) 議聚霜,是一種二進制協(xié)議,主要用于服務(wù)器和低功耗IoT(物聯(lián)網(wǎng))設(shè)備間的通信珠叔。該協(xié)議支持所有平 臺蝎宇,幾乎可以把所有聯(lián)網(wǎng)物品和外部連接起來,被用來當(dāng)做傳感器和致動器的通信協(xié)議祷安。 RabbitMQ通 過插件可以支持該協(xié)議姥芥。
二、RocketMQ概述
1汇鞭、RocketMQ簡介
RocketMQ是一個統(tǒng)一消息引擎凉唐、輕量級數(shù)據(jù)處理平臺庸追。 RocketMQ是?款阿?巴巴開源的消息中間件。2016年11?28?台囱,阿?巴巴向 Apache 軟件基?會捐贈 RocketMQ淡溯,成為 Apache 孵化項?。2017 年 9 ? 25 ?簿训,Apache 宣布 RocketMQ孵化成為 Apache 頂 級項?(TLP )血筑,成為國內(nèi)?個互聯(lián)?中間件在 Apache 上的頂級項?。
官網(wǎng)地址:http://rocketmq.apache.org/
2煎楣、RocketMQ發(fā)展歷程
[圖片上傳失敗...(image-7ed1b-1653707805237)]
- 2007年豺总,阿里開始五彩石項目,Notify作為項目中交易核心消息流轉(zhuǎn)系統(tǒng)择懂,應(yīng)運而生喻喳。Notify系統(tǒng)是 RocketMQ的雛形。
- 2010年困曙,B2B大規(guī)模使用ActiveMQ作為阿里的消息內(nèi)核表伦。阿里急需一個具有海量堆積能力的消息系統(tǒng)。
- 2011年初慷丽,Kafka開源蹦哼。淘寶中間件團隊在對Kafka進行了深入研究后,開發(fā)了一款新的MQ要糊,MetaQ纲熏。
- 2012年,MetaQ發(fā)展到了v3.0版本锄俄,在它基礎(chǔ)上進行了進一步的抽象局劲,形成了RocketMQ,然后就將其 進行了開源奶赠。
- 2015年鱼填,阿里在RocketMQ的基礎(chǔ)上,又推出了一款專門針對阿里云上用戶的消息系統(tǒng)Aliware MQ毅戈。
- 2016年雙十一苹丸,RocketMQ承載了萬億級消息的流轉(zhuǎn),跨越了一個新的里程碑苇经。11?28?赘理,阿?巴巴 向 Apache 軟件基?會捐贈 RocketMQ,成為 Apache 孵化項?塑陵。
- 2017 年 9 ? 25 ?感憾,Apache 宣布 RocketMQ孵化成為 Apache 頂級項?(TLP ),成為國內(nèi)?個互聯(lián) ?中間件在 Apache 上的頂級項?。
3阻桅、基本概念
1)消息(Message)
消息是指凉倚,消息系統(tǒng)所傳輸信息的物理載體,生產(chǎn)和消費數(shù)據(jù)的最小單位嫂沉,每條消息必須屬于一個主題稽寒。
2)主題(Topic)
[圖片上傳失敗...(image-eae-1653707805237)]
Topic表示一類消息的集合,每個主題包含若干條消息趟章,每條消息只能屬于一個主題杏糙,是RocketMQ進行 消息訂閱的基本單位。
topic:message 1:n
message:topic 1:1
producer:topic 1:n
consumer:topic 1:1
一個生產(chǎn)者可以同時發(fā)送多種Topic的消息蚓土;而一個消費者只對某種特定的Topic感興趣宏侍,即只可以訂閱 和消費一種Topic的消息。
3)標(biāo)簽(Tag)
為消息設(shè)置的標(biāo)簽蜀漆,用于同一主題下區(qū)分不同類型的消息谅河。來自同一業(yè)務(wù)單元的消息逼争,可以根據(jù)不同業(yè) 務(wù)目的在同一主題下設(shè)置不同標(biāo)簽镣隶。標(biāo)簽?zāi)軌蛴行У乇3执a的清晰度和連貫性,并優(yōu)化RocketMQ提 供的查詢系統(tǒng)忽刽。消費者可以根據(jù)Tag實現(xiàn)對不同子主題的不同消費邏輯鲜侥,實現(xiàn)更好的擴展性褂始。
Topic是消息的一級分類,Tag是消息的二級分類描函。
Topic:貨物
tag=上海
tag=江蘇
tag=浙江
------- 消費者 -----
topic=貨物 tag = 上海
topic=貨物 tag = 上海|浙江
topic=貨物 tag = *
4)隊列(Queue)
存儲消息的物理實體崎苗。一個Topic中可以包含多個Queue,每個Queue中存放的就是該Topic的消息赘阀。
一個Topic的Queue也被稱為一個Topic中消息的分區(qū)(Partition)益缠。 一個Topic的Queue中的消息只能被一個消費者組中的一個消費者消費。一個Queue中的消息不允許同 一個消費者組中的多個消費者同時消費基公。
[圖片上傳失敗...(image-48e7a2-1653707805237)]
5)消息標(biāo)識(MessageId/Key)
RocketMQ中每個消息擁有唯一的MessageId,且可以攜帶具有業(yè)務(wù)標(biāo)識的Key宋欺,以方便對消息的查詢轰豆。 不過需要注意的是,MessageId有兩個:在生產(chǎn)者send()消息時會自動生成一個MessageId(msgId)齿诞, 當(dāng)消息到達Broker后酸休,Broker也會自動生成一個MessageId(offsetMsgId)。msgId祷杈、offsetMsgId與key都 稱為消息標(biāo)識斑司。
- msgId:由producer端生成,其生成規(guī)則為: producerIp + 進程pid + MessageClientIDSetter類的ClassLoader的hashCode + 當(dāng)前時間 + AutomicInteger自增計數(shù)器
- offsetMsgId:由broker端生成但汞,其生成規(guī)則為:brokerIp + 物理分區(qū)的offset(Queue中的 偏移量)
- key:由用戶指定的業(yè)務(wù)相關(guān)的唯一標(biāo)識
4宿刮、系統(tǒng)架構(gòu)
[圖片上傳失敗...(image-e5b7dd-1653707805237)]
RocketMQ架構(gòu)上主要分為四部分構(gòu)成:
1)Producer
消息生產(chǎn)者互站,負(fù)責(zé)生產(chǎn)消息。Producer通過MQ的負(fù)載均衡模塊選擇相應(yīng)的Broker集群隊列進行消息投 遞僵缺,投遞的過程支持快速失敗并且低延遲胡桃。
例如,業(yè)務(wù)系統(tǒng)產(chǎn)生的日志寫入到MQ的過程磕潮,就是消息生產(chǎn)的過程
再如翠胰,電商平臺中用戶提交的秒殺請求寫入到MQ的過程,就是消息生產(chǎn)的過程
RocketMQ中的消息生產(chǎn)者都是以生產(chǎn)者組(Producer Group)的形式出現(xiàn)的自脯。生產(chǎn)者組是同一類生產(chǎn) 者的集合之景,這類Producer發(fā)送相同Topic類型的消息。一個生產(chǎn)者組可以同時發(fā)送多個主題的消息膏潮。
2)Consumer
消息消費者锻狗,負(fù)責(zé)消費消息。一個消息消費者會從Broker服務(wù)器中獲取到消息戏罢,并對消息進行相關(guān)業(yè)務(wù) 處理屋谭。
例如,QoS系統(tǒng)從MQ中讀取日志龟糕,并對日志進行解析處理的過程就是消息消費的過程桐磁。
再如,電商平臺的業(yè)務(wù)系統(tǒng)從MQ中讀取到秒殺請求讲岁,并對請求進行處理的過程就是消息消費的過程我擂。
RocketMQ中的消息消費者都是以消費者組(Consumer Group)的形式出現(xiàn)的。
消費者組是同一類消 費者的集合缓艳,這類Consumer消費的是同一個Topic類型的消息校摩。
消費者組使得在消息消費方面,實現(xiàn)負(fù)載均衡(將一個Topic中的不同的Queue平均分配給同一個Consumer Group的不同的Consumer阶淘,注 意衙吩,并不是將消息負(fù)載均衡)和容錯(一個Consmer掛了,該Consumer Group中的其它Consumer可 以接著消費原Consumer消費的Queue)的目標(biāo)變得非常容易
[圖片上傳失敗...(image-b0ea66-1653707805237)]
消費者組中Consumer的數(shù)量應(yīng)該小于等于訂閱Topic的Queue數(shù)量溪窒。如果超出Queue數(shù)量坤塞,則多出的 Consumer將不能消費消息。
[圖片上傳失敗...(image-93d65f-1653707805237)]
不過澈蚌,一個Topic類型的消息可以被多個消費者組同時消費摹芙。
消費者組只能消費一個Topic的消息,不能同時消費多個Topic消息
一個消費者組中的消費者必須訂閱完全相同的Topic
3)Name Server
功能介紹
NameServer是一個Broker與Topic路由的注冊中心宛瞄,支持Broker的動態(tài)注冊與發(fā)現(xiàn)浮禾。
RocketMQ的思想來自于Kafka,而Kafka是依賴了Zookeeper的。所以盈电,在RocketMQ的早期版本蝴簇,即在 MetaQ v1.0與v2.0版本中,也是依賴于Zookeeper的挣轨。從MetaQ v3.0军熏,即RocketMQ開始去掉了 Zookeeper依賴,使用了自己的NameServer卷扮。
主要包括兩個功能:
- Broker管理:接受Broker集群的注冊信息并且保存下來作為路由信息的基本數(shù)據(jù)荡澎;提供心跳檢測 機制,檢查Broker是否還存活晤锹。
- 路由信息管理:每個NameServer中都保存著Broker集群的整個路由信息和用于客戶端查詢的隊列 信息摩幔。Producer和Conumser通過NameServer可以獲取整個Broker集群的路由信息,從而進行消 息的投遞和消費鞭铆。
路由注冊
NameServer通常也是以集群的方式部署或衡,不過,NameServer是無狀態(tài)的车遂,即NameServer集群中的各 個節(jié)點間是無差異的封断,各節(jié)點間相互不進行信息通訊。那各節(jié)點中的數(shù)據(jù)是如何進行數(shù)據(jù)同步的呢舶担?在 Broker節(jié)點啟動時坡疼,輪詢NameServer列表,與每個NameServer節(jié)點建立長連接衣陶,發(fā)起注冊請求柄瑰。在 NameServer內(nèi)部維護著?個Broker列表,用來動態(tài)存儲Broker的信息剪况。
注意教沾,這是與其它像zk、Eureka译断、Nacos等注冊中心不同的地方授翻。
這種NameServer的無狀態(tài)方式,有什么優(yōu)缺點?
優(yōu)點:NameServer集群搭建簡單孙咪,擴容簡單藏姐。
缺點:對于Broker,必須明確指出所有NameServer地址该贾。否則未指出的將不會去注冊。也正因 為如此捌臊,NameServer并不能隨便擴容杨蛋。因為,若Broker不重新配置,新增的NameServer對于 Broker來說是不可見的逞力,其不會向這個NameServer進行注冊曙寡。
Broker節(jié)點為了證明自己是活著的,為了維護與NameServer間的長連接寇荧,會將最新的信息以心跳包
的 方式上報給NameServer举庶,每30秒發(fā)送一次心跳。心跳包中包含 BrokerId揩抡、Broker地址(IP+Port)户侥、 Broker名稱、Broker所屬集群名稱等等峦嗤。NameServer在接收到心跳包后蕊唐,會更新心跳時間戳,記錄這 個Broker的最新存活時間烁设。
路由剔除
由于Broker關(guān)機替梨、宕機或網(wǎng)絡(luò)抖動等原因,NameServer沒有收到Broker的心跳装黑,NameServer可能會將 其從Broker列表中剔除副瀑。
NameServer中有?個定時任務(wù),每隔10秒就會掃描?次Broker表恋谭,查看每一個Broker的最新心跳時間 戳距離當(dāng)前時間是否超過120秒糠睡,如果超過,則會判定Broker失效箕别,然后將其從Broker列表中剔除铜幽。
擴展:對于RocketMQ日常運維工作,例如Broker升級串稀,需要停掉Broker的工作除抛。OP需要怎么 做?
OP需要將Broker的讀寫權(quán)限禁掉母截。一旦client(Consumer或Producer)向broker發(fā)送請求到忽,都會收 到broker的NO_PERMISSION響應(yīng),然后client會進行對其它Broker的重試清寇。
當(dāng)OP觀察到這個Broker沒有流量后喘漏,再關(guān)閉它,實現(xiàn)Broker從NameServer的移除华烟。
OP:運維工程師
SRE:Site Reliability Engineer翩迈,現(xiàn)場可靠性工程師
路由發(fā)現(xiàn)
RocketMQ的路由發(fā)現(xiàn)采用的是Pull模型。當(dāng)Topic路由信息出現(xiàn)變化時盔夜,NameServer不會主動推送給 客戶端负饲,而是客戶端定時拉取主題最新的路由堤魁。默認(rèn)客戶端每30秒會拉取一次最新的路由。
擴展:
① Push模型:推送模型返十。其實時性較好妥泉,是一個“發(fā)布-訂閱”模型,需要維護一個長連接洞坑。而 長連接的維護是需要資源成本的盲链。該模型適合于的場景:
- 實時性要求較高
- Client數(shù)量不多,Server數(shù)據(jù)變化較頻繁迟杂。
② Pull模型:拉取模型刽沾。存在的問題是,實時性較差逢慌。
③ Long Polling模型:長輪詢模型悠轩。其是對Push與Pull模型的整合,充分利用了這兩種模型的優(yōu) 勢攻泼,屏蔽了它們的劣勢火架。
客戶端NameServer選擇策略
這里的客戶端指的是Producer
與Consumer
客戶端在配置時必須要寫上NameServer集群的地址,那么客戶端到底連接的是哪個NameServer節(jié)點 呢忙菠?客戶端首先會生產(chǎn)一個隨機數(shù)何鸡,然后再與NameServer節(jié)點數(shù)量取模,此時得到的就是所要連接的 節(jié)點索引牛欢,然后就會進行連接骡男。如果連接失敗,則會采用round-robin策略傍睹,逐個嘗試著去連接其它節(jié) 點隔盛。
首先采用的是隨機策略
進行的選擇,失敗后采用的是輪詢策略
拾稳。
擴展:Zookeeper Client是如何選擇Zookeeper Server的吮炕?
簡單來說就是,經(jīng)過兩次Shuf?e访得,然后選擇第一臺Zookeeper Server龙亲。
詳細(xì)說就是,將配置文件中的zk server地址進行第一次shuf?e悍抑,然后隨機選擇一個鳄炉。這個選擇出 的一般都是一個hostname。然后獲取到該hostname對應(yīng)的所有ip搜骡,再對這些ip進行第二次 shuf?e拂盯,從shuf?e過的結(jié)果中取第一個server地址進行連接。
4)Broker
功能介紹
Broker充當(dāng)著消息中轉(zhuǎn)角色记靡,負(fù)責(zé)存儲消息磕仅、轉(zhuǎn)發(fā)消息珊豹。Broker在RocketMQ系統(tǒng)中負(fù)責(zé)接收并存儲從 生產(chǎn)者發(fā)送來的消息,同時為消費者的拉取請求作準(zhǔn)備榕订。Broker同時也存儲著消息相關(guān)的元數(shù)據(jù),包括 消費者組消費進度偏移offset蜕便、主題劫恒、隊列等。
Kafka 0.8版本之后轿腺,offset是存放在Broker中的两嘴,之前版本是存放在Zookeeper中的。
模塊構(gòu)成
下圖為Broker Server的功能模塊示意圖:
[圖片上傳失敗...(image-cdb421-1653707805237)]
- Remoting Module:整個Broker的實體族壳,負(fù)責(zé)處理來自clients端的請求憔辫。而這個Broker實體則由以下模 塊構(gòu)成。
- Client Manager:客戶端管理器仿荆。負(fù)責(zé)接收贰您、解析客戶端(Producer/Consumer)請求,管理客戶端拢操。例 如锦亦,維護Consumer的Topic訂閱信息
- Store Service:存儲服務(wù)。提供方便簡單的API接口令境,處理消息存儲到物理硬盤和消息查詢功能杠园。
- HA Service:高可用服務(wù),提供Master Broker 和 Slave Broker之間的數(shù)據(jù)同步功能舔庶。
- Index Service:索引服務(wù)抛蚁。根據(jù)特定的Message key,對投遞到Broker的消息進行索引服務(wù)惕橙,同時也提 供根據(jù)Message Key對消息進行快速查詢的功能瞧甩。
集群部署
[圖片上傳失敗...(image-7d0886-1653707805237)]
為了增強Broker性能與吞吐量,Broker一般都是以集群形式出現(xiàn)的吕漂。各集群節(jié)點中可能存放著相同 Topic的不同Queue亲配。不過,這里有個問題惶凝,如果某Broker節(jié)點宕機吼虎,如何保證數(shù)據(jù)不丟失呢?其解決 方案是苍鲜,將每個Broker集群節(jié)點進行橫向擴展思灰,即將Broker節(jié)點再建為一個HA集群,解決單點問題混滔。
Broker節(jié)點集群是一個主從集群洒疚,即集群中具有Master與Slave兩種角色歹颓。Master負(fù)責(zé)處理讀寫操作請 求,Slave負(fù)責(zé)對Master中的數(shù)據(jù)進行備份油湖。當(dāng)Master掛掉了巍扛,Slave則會自動切換為Master去工作。所以這個Broker集群是主從集群乏德。一個Master可以包含多個Slave撤奸,但一個Slave只能隸屬于一個Master。 Master與Slave 的對應(yīng)關(guān)系是通過指定相同的BrokerName喊括、不同的BrokerId 來確定的胧瓜。BrokerId為0表 示Master,非0表示Slave郑什。每個Broker與NameServer集群中的所有節(jié)點建立長連接府喳,定時注冊Topic信 息到所有NameServer。
5蘑拯、工作流程
具體流程
① 啟動NameServer钝满,NameServer啟動后開始監(jiān)聽端口,等待Broker强胰、Producer舱沧、Consumer連接。
② 啟動Broker時偶洋,Broker會與所有的NameServer建立并保持長連接熟吏,然后每30秒向NameServer定時 發(fā)送心跳包。
③ 發(fā)送消息前玄窝,可以先創(chuàng)建Topic牵寺,創(chuàng)建Topic時需要指定該Topic要存儲在哪些Broker上,當(dāng)然恩脂,在創(chuàng) 建Topic時也會將Topic與Broker的關(guān)系寫入到NameServer中帽氓。不過,這步是可選的俩块,也可以在發(fā)送消 息時自動創(chuàng)建Topic黎休。
④ Producer發(fā)送消息,啟動時先跟NameServer集群中的其中一臺建立長連接玉凯,并從NameServer中獲 取路由信息势腮,即當(dāng)前發(fā)送的Topic消息的Queue與Broker的地址(IP+Port)的映射關(guān)系。然后根據(jù)算法 策略從隊選擇一個Queue漫仆,與隊列所在的Broker建立長連接從而向Broker發(fā)消息捎拯。當(dāng)然,在獲取到路由 信息后盲厌,Producer會首先將路由信息緩存到本地署照,再每30秒從NameServer更新一次路由信息祸泪。
⑤ Consumer跟Producer類似,跟其中一臺NameServer建立長連接建芙,獲取其所訂閱Topic的路由信息没隘, 然后根據(jù)算法策略從路由信息中獲取到其所要消費的Queue,然后直接跟Broker建立長連接岁钓,開始消費 其中的消息升略。Consumer在獲取到路由信息后,同樣也會每30秒從NameServer更新一次路由信息屡限。不過 不同于Producer的是,Consumer還會向Broker發(fā)送心跳炕倘,以確保Broker的存活狀態(tài)钧大。
Topic的創(chuàng)建模式
手動創(chuàng)建Topic時,有兩種模式:
- 集群模式:該模式下創(chuàng)建的Topic在該集群中罩旋,所有Broker中的Queue數(shù)量是相同的啊央。
- Broker模式:該模式下創(chuàng)建的Topic在該集群中,每個Broker中的Queue數(shù)量可以不同涨醋。
自動創(chuàng)建Topic時瓜饥,默認(rèn)采用的是Broker模式,會為每個Broker默認(rèn)創(chuàng)建4個Queue浴骂。
讀/寫隊列
從物理上來講乓土,讀/寫隊列是同一個隊列。所以溯警,不存在讀/寫隊列數(shù)據(jù)同步問題趣苏。讀/寫隊列是邏輯上進 行區(qū)分的概念。一般情況下梯轻,讀/寫隊列數(shù)量是相同的食磕。
- 例如,創(chuàng)建Topic時設(shè)置的寫隊列數(shù)量為8喳挑,讀隊列數(shù)量為4彬伦,此時系統(tǒng)會創(chuàng)建8個Queue,分別是0 1 2 3 4 5 6 7伊诵。Producer會將消息寫入到這8個隊列单绑,但Consumer只會消費0 1 2 3這4個隊列中的消息,4 5 6 7中的消息是不會被消費到的日戈。
- 再如询张,創(chuàng)建Topic時設(shè)置的寫隊列數(shù)量為4,讀隊列數(shù)量為8浙炼,此時系統(tǒng)會創(chuàng)建8個Queue份氧,分別是0 1 2 3 4 5 6 7唯袄。Producer會將消息寫入到0 1 2 3 這4個隊列,但Consumer只會消費0 1 2 3 4 5 6 7這8個隊列中 的消息蜗帜,但是4 5 6 7中是沒有消息的恋拷。此時假設(shè)Consumer Group中包含兩個Consuer,Consumer1消 費0 1 2 3厅缺,而Consumer2消費4 5 6 7蔬顾。但實際情況是,Consumer2是沒有消息可消費的湘捎。
也就是說诀豁,當(dāng)讀/寫隊列數(shù)量設(shè)置不同時,總是有問題的窥妇。那么舷胜,為什么要這樣設(shè)計呢?
其這樣設(shè)計的目的是為了活翩,方便Topic的Queue的縮容烹骨。
例如,原來創(chuàng)建的Topic中包含16個Queue材泄,如何能夠使其Queue縮容為8個沮焕,還不會丟失消息?可以動 態(tài)修改寫隊列數(shù)量為8拉宗,讀隊列數(shù)量不變峦树。此時新的消息只能寫入到前8個隊列,而消費都消費的卻是 16個隊列中的數(shù)據(jù)簿废。當(dāng)發(fā)現(xiàn)后8個Queue中的消息消費完畢后空入,就可以再將讀隊列數(shù)量動態(tài)設(shè)置為8。整 個縮容過程族檬,沒有丟失任何消息歪赢。
perm用于設(shè)置對當(dāng)前創(chuàng)建Topic的操作權(quán)限:2表示只寫,4表示只讀单料,6表示讀寫埋凯。