什么叫消息隊列
消息(Message)是指在應(yīng)用間傳送的數(shù)據(jù)搬设。消息可以非常簡單,比如只包含文本字符串,也可以更復(fù)雜尽狠,可能包含嵌入對象。
消息隊列(Message Queue)是一種應(yīng)用間的通信方式叶圃,消息發(fā)送后可以立即返回袄膏,由消息系統(tǒng)來確保消息的可靠傳遞。消息發(fā)布者只管把消息發(fā)布到 MQ 中而不用管誰來取掺冠,消息使用者只管從 MQ 中取消息而不管是誰發(fā)布的沉馆。這樣發(fā)布者和使用者都不用知道對方的存在码党。
為何用消息隊列
從上面的描述中可以看出消息隊列是一種應(yīng)用間的異步協(xié)作機制,那什么時候需要使用 MQ 呢斥黑?
以常見的訂單系統(tǒng)為例揖盘,用戶點擊【下單】按鈕之后的業(yè)務(wù)邏輯可能包括:扣減庫存、生成相應(yīng)單據(jù)锌奴、發(fā)紅包兽狭、發(fā)短信通知。在業(yè)務(wù)發(fā)展初期這些邏輯可能放在一起同步執(zhí)行鹿蜀,隨著業(yè)務(wù)的發(fā)展訂單量增長箕慧,需要提升系統(tǒng)服務(wù)的性能,這時可以將一些不需要立即生效的操作拆分出來異步執(zhí)行茴恰,比如發(fā)放紅包颠焦、發(fā)短信通知等。這種場景下就可以用 MQ 往枣,在下單的主流程(比如扣減庫存伐庭、生成相應(yīng)單據(jù))完成之后發(fā)送一條消息到 MQ 讓主流程快速完結(jié),而由另外的單獨線程拉取MQ的消息(或者由 MQ 推送消息)分冈,當發(fā)現(xiàn) MQ 中有發(fā)紅包或發(fā)短信之類的消息時似忧,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。
以上是用于業(yè)務(wù)解耦的情況丈秩,其它常見場景包括最終一致性盯捌、廣播、錯峰流控等等蘑秽。
MQ應(yīng)用場景分析
消息隊列中間件是分布式系統(tǒng)的重要組件饺著,主要解決異步消息,應(yīng)用解耦肠牲,流量削鋒等問題幼衰,從而實現(xiàn)高性能,高可用缀雳,可伸縮和最終一致性的架構(gòu)渡嚣。
使用較多的消息隊列有ActiveMQ,RabbitMQ肥印,Kafka,MetaMQ等识椰。
1.1異步處理
場景說明:用戶注冊后,需要發(fā)送注冊郵件和注冊短信深碱。傳統(tǒng)的做法如下:
將注冊信息寫入數(shù)據(jù)庫成功后腹鹉,發(fā)送注冊郵件,在發(fā)送注冊短信敷硅。以上三個任務(wù)全部完成后功咒,返回給客戶端愉阎。
引入消息隊列,異步處理力奋,改造后的架構(gòu)如下:
1.2應(yīng)用解耦
場景說明:用戶下單后榜旦,訂單系統(tǒng)需要通知庫存系統(tǒng)。傳統(tǒng)的做法是景殷,訂單系統(tǒng)調(diào)用庫存系統(tǒng)的接口溅呢。如下圖:
傳統(tǒng)模式的缺點:
假如庫存系統(tǒng)無法訪問,則訂單減庫存將失敗滨彻,從而導(dǎo)致下單失敗藕届。
訂單系統(tǒng)與庫存系統(tǒng)耦合挪蹭。
引入消息隊列后:
訂單系統(tǒng):用戶下單后亭饵,訂單系統(tǒng)完成持久化處理,將消息寫入消息隊列梁厉,返回用戶辜羊,下單成功。
庫存系統(tǒng)词顾,訂閱下單的消息八秃,獲取下單信息,庫存系統(tǒng)根據(jù)下單信息肉盹,進行庫存操作昔驱。
假如:在下單時庫存系統(tǒng)不能正常使用。也不影響正常下單上忍,因為下單后骤肛,訂單系統(tǒng)寫入消息隊列就不在
關(guān)心其他的后續(xù)操作了,實現(xiàn)訂單系統(tǒng)與庫存系統(tǒng)的應(yīng)用解耦窍蓝。
1.3流量削鋒
一般在秒殺或團搶活動中廣泛使用腋颠。
應(yīng)用場景:秒殺活動,一般會因為流量過大吓笙,導(dǎo)致流量暴增淑玫,應(yīng)用掛掉。為解決這個問題面睛,一般需要在應(yīng)用前端加入消息隊列絮蒿。
可以控制活動的人數(shù)。
可以緩解短時間內(nèi)高流量壓垮應(yīng)用叁鉴。
用戶的請求歌径,服務(wù)器接收后,首先寫入消息隊列亲茅,假如消息的隊列長度超過最大數(shù)量回铛,則直接拋棄用戶請求或跳轉(zhuǎn)到錯誤界面狗准。
秒殺業(yè)務(wù)根據(jù)消息隊列中的請求信息,在做后續(xù)處理茵肃。
RabbitMQ 特點
RabbitMQ 是一個由 Erlang 語言開發(fā)的 AMQP 的開源實現(xiàn)腔长。
AMQP :Advanced Message Queue,高級消息隊列協(xié)議验残。它是應(yīng)用層協(xié)議的一個開放標準捞附,為面向消息的中間件設(shè)計,基于此協(xié)議的客戶端與消息中間件可傳遞消息您没,并不受產(chǎn)品鸟召、開發(fā)語言等條件的限制。
RabbitMQ 最初起源于金融系統(tǒng)氨鹏,用于在分布式系統(tǒng)中存儲轉(zhuǎn)發(fā)消息欧募,在易用性、擴展性仆抵、高可用性等方面表現(xiàn)不俗跟继。具體特點包括:
-
可靠性(Reliability)
RabbitMQ 使用一些機制來保證可靠性,如持久化镣丑、傳輸確認舔糖、發(fā)布確認。
-
靈活的路由(Flexible Routing)
在消息進入隊列之前莺匠,通過 Exchange 來路由消息的金吗。對于典型的路由功能,RabbitMQ 已經(jīng)提供了一些內(nèi)置的 Exchange 來實現(xiàn)趣竣。針對更復(fù)雜的路由功能摇庙,可以將多個 Exchange 綁定在一起,也通過插件機制實現(xiàn)自己的 Exchange 期贫。
-
消息集群(Clustering)
多個 RabbitMQ 服務(wù)器可以組成一個集群跟匆,形成一個邏輯 Broker 。
-
高可用(Highly Available Queues)
隊列可以在集群中的機器上進行鏡像通砍,使得在部分節(jié)點出問題的情況下隊列仍然可用玛臂。
-
多種協(xié)議(Multi-protocol)
RabbitMQ 支持多種消息隊列協(xié)議,比如 STOMP封孙、MQTT 等等迹冤。
-
多語言客戶端(Many Clients)
RabbitMQ 幾乎支持所有常用語言,比如 Java虎忌、.NET泡徙、Ruby 等等。
-
管理界面(Management UI)
RabbitMQ 提供了一個易用的用戶界面膜蠢,使得用戶可以監(jiān)控和管理消息 Broker 的許多方面堪藐。
-
跟蹤機制(Tracing)
如果消息異常莉兰,RabbitMQ 提供了消息跟蹤機制,使用者可以找出發(fā)生了什么礁竞。
-
插件機制(Plugin System)
RabbitMQ 提供了許多插件糖荒,來從多方面進行擴展,也可以編寫自己的插件模捂。
RabbitMQ 中的概念模型
消息模型
所有 MQ 產(chǎn)品從模型抽象上來說都是一樣的過程:消費者(consumer)訂閱某個隊列捶朵。生產(chǎn)者(producer)創(chuàng)建消息,然后發(fā)布到隊列(queue)中狂男,最后將消息發(fā)送到監(jiān)聽的消費者综看。
[圖片上傳失敗...(image-96e1c8-1573552839175)]
RabbitMQ 基本概念
上面只是最簡單抽象的描述,具體到 RabbitMQ 則有更詳細的概念需要解釋岖食。上面介紹過 RabbitMQ 是 AMQP 協(xié)議的一個開源實現(xiàn)红碑,所以其內(nèi)部實際上也是 AMQP 中的基本概念:
[圖片上傳失敗...(image-307637-1573552839175)]
Message
消息,消息是不具名的县耽,它由消息頭和消息體組成句喷。消息體是不透明的镣典,而消息頭則由一系列的可選屬性組成兔毙,這些屬性包括routing-key(路由鍵)、priority(相對于其他消息的優(yōu)先權(quán))兄春、delivery-mode(指出該消息可能需要持久性存儲)等澎剥。
Publisher
消息的生產(chǎn)者,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序赶舆。
Exchange
交換器哑姚,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列。
Binding
綁定芜茵,用于消息隊列和交換器之間的關(guān)聯(lián)叙量。一個綁定就是基于路由鍵將交換器和消息隊列連接起來的路由規(guī)則,所以可以將交換器理解成一個由綁定構(gòu)成的路由表九串。
Queue
消息隊列绞佩,用來保存消息直到發(fā)送給消費者。它是消息的容器猪钮,也是消息的終點品山。一個消息可投入一個或多個隊列。消息一直在隊列里面烤低,等待消費者連接到這個隊列將其取走肘交。
Connection
網(wǎng)絡(luò)連接,比如一個TCP連接扑馁。
Channel
信道涯呻,多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道凉驻。信道是建立在真實的TCP連接內(nèi)地虛擬連接,AMQP 命令都是通過信道發(fā)出去的复罐,不管是發(fā)布消息沿侈、訂閱隊列還是接收消息,這些動作都是通過信道完成市栗。因為對于操作系統(tǒng)來說建立和銷毀 TCP 都是非常昂貴的開銷缀拭,所以引入了信道的概念,以復(fù)用一條 TCP 連接填帽。
Consumer
消息的消費者蛛淋,表示一個從消息隊列中取得消息的客戶端應(yīng)用程序。
Virtual Host
虛擬主機篡腌,表示一批交換器褐荷、消息隊列和相關(guān)對象。虛擬主機是共享相同的身份認證和加密環(huán)境的獨立服務(wù)器域嘹悼。每個 vhost 本質(zhì)上就是一個 mini 版的 RabbitMQ 服務(wù)器叛甫,擁有自己的隊列、交換器杨伙、綁定和權(quán)限機制其监。vhost 是 AMQP 概念的基礎(chǔ),必須在連接時指定限匣,RabbitMQ 默認的 vhost 是 / 抖苦。
Broker
表示消息隊列服務(wù)器實體。