特別聲明:強(qiáng)烈建議想要學(xué)習(xí)MQ的同學(xué)如果有時間慢慢啃的話還是推薦直接去官網(wǎng)看英文doc沉删,遇到實在不理解的地方再去博客或者其他網(wǎng)站上找資料织中。
接下來步入正題:AMQP本質(zhì)是一個消息隊列協(xié)議而并非一個框架,我們熟知的RabbitMQ艳悔,RocketMQ才是實現(xiàn)了AMQP的消息隊列框架弄兜。Spring默認(rèn)的AMQP實現(xiàn)也是唯一的實現(xiàn)是RabbitMQ少欺。至于阿里的火箭MQ白翻,apache的activeMQ就沒有提供實現(xiàn)啦乍炉。至于以上這些MQ框架孰優(yōu)孰劣,要根據(jù)實際情況自己判斷了滤馍。本人更偏向于使用RabbitMQ岛琼,一個因為是Spring對其進(jìn)行了封裝,使用起來比較簡單巢株。槐瑞。。(最主要的原因)阁苞,二是因為本身他是Erlang語言編寫困檩,對于并發(fā)的支持較好祠挫,而且網(wǎng)上的各家MQ的性能測試對比中表現(xiàn)的也比較好。
首先介紹AMQP中幾個重要的概念:下面這張圖片是RabbitMQ官網(wǎng)中對于AMQP模型的抽象
如圖悼沿,整個消息流轉(zhuǎn)的過程是:生產(chǎn)者將消息發(fā)送到Exchange中茸歧,Exchange再將消息根據(jù)一定的規(guī)則路由到指定的隊列中,最后消費者從指定的隊列中獲取消息显沈。其中被方框圈起來的組件可以稱為Broker,即MQ服務(wù)器逢唤,Publisher和Consumer就是我們自己實現(xiàn)的生產(chǎn)者和消費者拉讯。接下來詳細(xì)介紹一下上面的幾個組件。
Exchange
Exchange(交換機(jī))類型:他是生產(chǎn)者發(fā)送消息的地方鳖藕,交換機(jī)收到消息后將消息路由到0或多個隊列中魔慷,AMQP一共定義了4種交換機(jī),如圖:
其實還有一個Default Exchange著恩,只不過它是被MQ服務(wù)器提前聲明的一種沒有名字的Direct exchange院尔。但是它有一個很重要的屬性,創(chuàng)建的每一個隊列都會自動的用隊列名作為路由鍵(路由key路由的規(guī)則)綁定到該exchange中喉誊。打個比方邀摆,比如你創(chuàng)建了一個名稱為“talk-is-cheap——show-me-the-code”的隊列,MQ會自動的用“talk-is-cheap——show-me-the-code”作為路由key綁定到Default exchange伍茄,所以當(dāng)生產(chǎn)者發(fā)送的消息攜帶名為“talk-is-cheap——show-me-the-code”的路由key時就會發(fā)送到聲明的隊列中去了栋盹。
Direct exchange:
他是根據(jù)路由key將消息發(fā)送到指定隊列,比較適合一對一的場景敷矫。工作流程如下:聲明隊列時指定一個路由key綁定到exchange例获,當(dāng)有攜帶相同key的消息到達(dá)exchange中時就會自動的轉(zhuǎn)發(fā)給該隊列了。
Fanout? exchange:
如圖曹仗,該交換機(jī)是將消息轉(zhuǎn)發(fā)到所有綁定到該交換機(jī)上的隊列榨汤,這個時候如果你發(fā)給交換機(jī)的消息攜帶路由key,他也會忽略掉怎茫。這個場景最適合的就是廣播了收壕,類似村書記喇叭一喊,大家都能聽到了轨蛤。這里貼幾個官網(wǎng)對于該交換機(jī)幾個使用場景的介紹啼器。
大型多玩家在線(MMO)游戲可以使用它來更新排行榜或其他全球事件
體育新聞網(wǎng)站可以使用fanout交換器向移動客戶實時分發(fā)分?jǐn)?shù)更新
分布式系統(tǒng)可以廣播各種狀態(tài)和配置更新(記得Spring Cloud Bus的配置廣播嗎?)
Topic Exchange:
他通過一定的路由策略將符合條件的路由key轉(zhuǎn)發(fā)到多個符合路由策略的隊列上俱萍,和直連交換機(jī)類似端壳,只不過他匹配的是key的模式,類似于正則匹配枪蘑。其中*代表任意的一個詞损谦,#代表0或多個詞岖免。使用場景比如這個任務(wù)隊列里的消息需要多個消費者處理,而每個消費者只能處理特定的任務(wù)照捡。
Headers Exchange:
類似于http的head颅湘,可以設(shè)置多個屬性,根據(jù)屬性進(jìn)行隊列匹配栗精。首部交換機(jī)也會忽略路由鍵闯参。當(dāng)有多個首部的時候怎么知道該匹配哪一個呢?交換機(jī)有一個“x-match”參數(shù)悲立,設(shè)置為any表示任意一個匹配即可鹿寨,設(shè)置為all則表示所有的頭部信息都匹配才會發(fā)送到指定隊列。這個交換機(jī)工作中不咋用薪夕,好像略微有點雞肋脚草。
Queue
呃,這個其實和普通的隊列沒啥區(qū)別原献,只不過它里面可以設(shè)置一些額外的屬性馏慨,例如持久化、自動刪除等姑隅。有一個地方需要注意写隶,如果不能將AMQP消息路由到任何隊列(例如,路由鍵沒有對應(yīng)的隊列)讲仰,則可以根據(jù)發(fā)布者設(shè)置的消息屬性樟澜,將其刪除或返回給發(fā)布者。這個設(shè)置在保證消息可靠性時是十分重要的叮盘。(關(guān)于如何保證消息可靠性可以看這篇文章RabbitMQ消息可靠性分析)