應(yīng)一些小伙伴們的私信,希望可以介紹一下RocketMQ的基礎(chǔ),那么我們現(xiàn)在就從0開始,進(jìn)入RocketMQ的基礎(chǔ)學(xué)習(xí)及概念介紹,為學(xué)習(xí)和使用RocketMQ打好基礎(chǔ)!
RocketMQ是一款快速地、可靠地、分布式、容易使用的消息中間件,由Alibaba開發(fā),其前身是 Metaq,Metaq 可以看成是linkedin的Kafka(scala)的java版本,并對其增加了事務(wù)的支持。
RocketMQ為Metaq3.0,相比于原始kafka,其擅長點出了原始的 log collecting之外,還增加諸如HA、事務(wù)等特性,使得從功能上可以替代傳統(tǒng)大部分 MQ。
- 可靠的FIFO和嚴(yán)格的消息順序
- Pub/Sub 和 P2P 消息模型
- 單隊列容納百萬消息的能力
- 拉(Pull)和推(push)隊列
- 各種消息協(xié)議,如 JMS,MQTT 等
- 分布式集群,支持容錯
- Docker images for isolated testing and cloud Isolated clusters
- 豐富的配置和監(jiān)控功能的管理
Topic 是一個主題。一個系統(tǒng)中,我們可以將消息劃成 Topic ,這樣,將不同的消息發(fā)送到不同的 queue。
-
一個topic下,我們可以設(shè)置多個queue,每個queue就是我們平時所說的消息隊列;
-
因為queue是完全從屬于某個特定的topic的,所以當(dāng)我們要發(fā)送消息時,總是要指定該消息所屬的topic是什么。
-
通過equeue就能知道該topic下有幾個queue了,但是到底發(fā)送到哪個queue呢?比如topic下有4個queue,那對于這個topic下的消息,發(fā)送時,到底該發(fā)送到哪個queue呢?
-
目前,equeue的做法是在發(fā)送一個消息時,需要用戶指定這個消息對應(yīng)的topic以及一個用來路由的一個object類型的參數(shù)。
-
equeue會根據(jù)topic得到所有的queue,然后根據(jù)該object參數(shù)通過hash code然后取模queue的個數(shù)最后得到要發(fā)送的queue的編號,從而知道該發(fā)送到哪個queue。
-
這個路由消息的過程是在發(fā)送消息的這一方做的,也就是下面要說的producer。之所以不在消息服務(wù)器上做是因為這樣可以讓用戶自己決定該如何路由消息,具有更大的靈活性。
消息隊列的生產(chǎn)者。我們知道,消息隊列的本質(zhì)就是實現(xiàn)了publish-subscribe的模式,即生產(chǎn)者-消費者模式。生產(chǎn)者生產(chǎn)消息,消費者消費消息。所以這里的Producer就是用來生產(chǎn)和發(fā)送消息的。
消息隊列的消費者,一個消息可以有多個消費者。
消費者分組,這可能對大家來說是一個新概念。之所以要搞出一個消費者分組, 是為了實現(xiàn)下面要說的集群消費。一個消費者分組中包含了一些消費者,如果這些消費者是要集群消費,那這些消費者會平均消費該分組中的消息。
-
equeue中的broker負(fù)責(zé)消息的中轉(zhuǎn),即接收producer發(fā)送過來的消息,然后持久化消息到磁盤,然后接收consumer發(fā)送過來的拉取消息的請求,然后根據(jù)請求拉取相應(yīng)的消息給consumer。
-
所以,broker可以理解為消息隊列服務(wù)器,提供消息的接收、存儲、拉取服務(wù)。
-
broker對于equeue來說是核心,它絕對不能掛,一旦掛了,那producer,consumer就無法實現(xiàn)publish-subscribe了。
-
使用CPU資源來換取網(wǎng)卡流量資源;
-
FilterServer與Broker部署在同一臺機器,數(shù)據(jù)通過本地回環(huán)通信,不走網(wǎng)卡;
-
一臺Broker部署多個FilterServer,充分利用CPU資源,因為單個JVM難以全面利用高配的物理機CPU資源;
-
因為過濾代碼使用Java編寫,應(yīng)用幾乎可以做任意形式的服務(wù)器端消息過濾,例如通過Messgae Header進(jìn)行過濾,甚至可以按照Message Body進(jìn)行過濾;
-
使用Java語言進(jìn)行作為過濾表達(dá)式是一個雙刃劍,方便了應(yīng)用的過濾操作,但是帶來了服務(wù)器端的安全風(fēng)險。需要應(yīng)用來保證過濾代碼安全,例如在過濾程序中盡可能不做申請大內(nèi)存,創(chuàng)建線程等操作,避免Broker服務(wù)器發(fā)生資源泄露。
-
SEND_OK:消息發(fā)送成功;
-
FLUSH_DISK_TIMEOUT:消息發(fā)送成功,但是服務(wù)器刷盤超時,消息已經(jīng)進(jìn)入服務(wù)器隊列,只有此時服務(wù)器宕機,消息才會丟失;
-
FLUSH_SLAVE_TIMEOUT:消息發(fā)送成功,但是服務(wù)器同步到slave時超時,消息已經(jīng)進(jìn)入服務(wù)器隊列,只有此次服務(wù)器宕機,消息才會丟失;
-
SLAVE_NOT_AVAILABLE:消息發(fā)送成功,但是此時slave不可用,消息已經(jīng)進(jìn)入服務(wù)器隊列,只有此時服務(wù)器宕機,消息才會丟失;
集群消費是指,一個consumer group下的consumer,平均消費topic下的queue。
- 假如一個topic下有4個queue,然后當(dāng)前有一個consumer group,該分組下有4個consumer,那每個consumer就被分配到該topic下的一個queue,這樣就達(dá)到了平均消費topic下的queue的目的。
- 如果consumer group下只有兩個consumer,那每個consumer就消費2個queue。
- 如果有3個consumer,則第一個消費2個queue,后面兩個每個消費一個queue,從而達(dá)到盡量平均消費。
應(yīng)該盡量讓consumer group下的consumer的數(shù)目和topic的queue的數(shù)目一致或成倍數(shù)關(guān)系。這樣每個consumer消費的queue的數(shù)量總是一樣的,這樣每個consumer服務(wù)器的壓力才會差不多。當(dāng)前前提是這個topic下的每個queue里的消息的數(shù)量總是差不多多的。這點我們可以對消息根據(jù)某個用戶自己定義的key來進(jìn)行hash路由來保證。
廣播消費是指一個consumer只要訂閱了某個topic的消息,那它就會收到該topic下的所有queue里的消息,而不管這個consumer的group是什么。所以對于廣播消費來說,consumer group沒什么實際意義。consumer可以在實例化時,我們可以指定是集群消費還是廣播消費。
對于集群消費和廣播消費,消費進(jìn)度持久化的地方是不同的,集群消費的消費進(jìn)度是放在broker,也就是消息隊列服務(wù)器上的,而廣播消費的消費進(jìn)度是存儲在consumer本地磁盤上的。
- *由于一個queue的消費者可能會更換,因為consumer group下的consumer數(shù)量可能會增加或減少,然后就會重新計算每個consumer該消費的queue是哪些,所以,當(dāng)出現(xiàn)一個queue的consumer變動的時候,新的consumer如何知道該從哪里開始消費這個queue呢?
如果這個queue的消費進(jìn)度是存儲在前一個consumer服務(wù)器上的,那就很難拿到這個消費進(jìn)度了,因為有可能那個服務(wù)器已經(jīng)掛了,或者下架了,都有可能。而因為broker對于所有的consumer總是在服務(wù)的,所以,在集群消費的情況下,被訂閱的topic的queue的消費位置是存儲在broker上的,存儲的時候按照不同的consumer group做隔離,以確保不同的consumer group下的consumer的消費進(jìn)度互補影響。
廣播消費,由于不會出現(xiàn)一個queue的consumer會變動的情況,所以我們沒必要讓broker來保存消費位置,所以是保存在consumer自己的服務(wù)器上。
消費進(jìn)度是指,當(dāng)一個consumer group里的consumer在消費某個queue里的消息時,equeue是通過記錄消費位置(offset)來知道當(dāng)前消費到哪里了。以便該consumer重啟后繼續(xù)從該位置開始消費。
比如一個topic有4個queue,一個consumer group有4個consumer,則每個consumer分配到一個queue,然后每個consumer分別消費自己的queue里的消息。
equeue會分別記錄每個consumer對其queue的消費進(jìn)度,從而保證每個consumer重啟后知道下次從哪里開始繼續(xù)消費。
實際上,也許下次重啟后不是由該consumer消費該queue了,而是由group里的其他consumer消費了,這樣也沒關(guān)系,因為我們已經(jīng)記錄了這個queue的消費位置了。
消費位置和consumer其實無關(guān),消費位置完全是queue的一個屬性,用來記錄當(dāng)前被消費到哪里了。另外一點很重要的是,一個topic可以被多個consumer group里的consumer訂閱。
不同consumer group里的consumer即便是消費同一個topic下的同一個queue,那消費進(jìn)度也是分開存儲的。也就是說,不同的consumer group內(nèi)的consumer的消費完全隔離,彼此不受影響。文章來源:http://www.zghlxwxcb.cn/news/detail-659065.html
分享資源
獲取以上資源請訪問開源項目 點擊跳轉(zhuǎn)文章來源地址http://www.zghlxwxcb.cn/news/detail-659065.html
到了這里,關(guān)于【Alibaba中間件技術(shù)系列】「RocketMQ技術(shù)專題」小白專區(qū)之領(lǐng)略一下RocketMQ基礎(chǔ)之最!的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!