RabbitMQ筆記一:消息隊(duì)列和RabbitMQ及AMQP協(xié)議介紹

打算最近寫(xiě)一系列的Rabbitmq的博客,很詳盡的講解MQ的方方面面,也便于自己以后在工作中回頭來(lái)總結(jié)整理。

為什么要使用消息隊(duì)列

  1. 異步處理
  2. 系統(tǒng)解耦
    解耦是消息中間隊(duì)列解決的最本質(zhì)問(wèn)題。所謂解耦,簡(jiǎn)單一點(diǎn)就是一個(gè)事務(wù),只關(guān)心核心的流程。而需要依賴(lài)其他系統(tǒng)但不那么重要的事情,有通知即可,無(wú)需等待結(jié)果。換句話(huà)說(shuō),關(guān)心的是“通知,而非“處理”。
    比如下單過(guò)程中,需要發(fā)送短信積分,如果下游系統(tǒng)過(guò)慢(比如短信網(wǎng)關(guān)速度不好),主流程一直在等待。用戶(hù)肯定不希望支付下單的過(guò)程中幾分鐘之后才得到結(jié)果。那么我們只需要通知短信系統(tǒng)“我們支付成功了”,不一定非要等待它處理完成。
  3. 流量削峰
    試想上下游對(duì)于事件的處理能力是不同的。比如,Web前端每秒承受上千萬(wàn)的請(qǐng)求,并不是什么神奇的事情,只需要加多一點(diǎn)機(jī)器,再搭建一些LVS負(fù)載均衡設(shè)備和Nginx等即可。但數(shù)據(jù)庫(kù)的處理能力卻十分有限,即使使用SSD加分庫(kù)分表,單機(jī)的處理能力仍然在萬(wàn)級(jí)。由于成本的考慮,我們不能奢求數(shù)據(jù)庫(kù)的機(jī)器數(shù)量追上前端。
    這種問(wèn)題同樣存在于系統(tǒng)和系統(tǒng)之間,如短信系統(tǒng)可能由于短板效應(yīng),速度卡在網(wǎng)關(guān)上(每秒幾百次請(qǐng)求),跟前端的并發(fā)量不是一個(gè)數(shù)量級(jí)。但用戶(hù)晚上個(gè)半分鐘左右收到短信,一般是不會(huì)有太大問(wèn)題的。如果沒(méi)有消息隊(duì)列,兩個(gè)系統(tǒng)之間通過(guò)協(xié)商、滑動(dòng)窗口等復(fù)雜的方案也不是說(shuō)不能實(shí)現(xiàn)。但系統(tǒng)復(fù)雜性指數(shù)級(jí)增長(zhǎng),勢(shì)必在上游或者下游做存儲(chǔ),并且要處理定時(shí)、擁塞等一系列問(wèn)題。而且每當(dāng)有處理能力有差距的時(shí)候,都需要單獨(dú)開(kāi)發(fā)一套邏輯來(lái)維護(hù)這套邏輯。所以,利用中間系統(tǒng)轉(zhuǎn)儲(chǔ)兩個(gè)系統(tǒng)的通信內(nèi)容,并在下游系統(tǒng)有能力處理這些消息的時(shí)候,再處理這些消息,是一套相對(duì)較通用的方式。
  4. 廣播
    消息隊(duì)列的基本功能之一是進(jìn)行廣播。如果沒(méi)有消息隊(duì)列,每當(dāng)一個(gè)新的業(yè)務(wù)方接入,我們都要聯(lián)調(diào)一次新接口。有了消息隊(duì)列,我們只需要關(guān)心消息是否送達(dá)了隊(duì)列,至于誰(shuí)希望訂閱,是下游的事情,無(wú)疑極大地減少了開(kāi)發(fā)和聯(lián)調(diào)的工作量。
  5. 最終一致性
    最終一致性指的是兩個(gè)系統(tǒng)的狀態(tài)保持一致,要么都成功,要么都失敗。當(dāng)然有個(gè)時(shí)間限制,理論上越快越好,但實(shí)際上在各種異常的情況下,可能會(huì)有一定延遲達(dá)到最終一致?tīng)顟B(tài),但最后兩個(gè)系統(tǒng)的狀態(tài)是一樣的。
    業(yè)界有一些為“最終一致性”而生的消息隊(duì)列,如Notify(阿里)、QMQ(去哪兒)等,其設(shè)計(jì)初衷,就是為了交易系統(tǒng)中的高可靠通知。

本地事務(wù)維護(hù)業(yè)務(wù)變化和通知消息,一起落地(失敗則一起回滾),然后RPC到達(dá)broker,在broker成功落地后,RPC返回成功,本地消息可以刪除。否則本地消息一直靠定時(shí)任務(wù)輪詢(xún)不斷重發(fā),這樣就保證了消息可靠落地broker。
broker往consumer發(fā)送消息的過(guò)程類(lèi)似,一直發(fā)送消息,直到consumer發(fā)送消費(fèi)成功確認(rèn)。

總結(jié)
消息隊(duì)列不是萬(wàn)能的。對(duì)于需要強(qiáng)事務(wù)保證而且延遲敏感的,RPC是優(yōu)于消息隊(duì)列的。
對(duì)于一些無(wú)關(guān)痛癢,或者對(duì)于別人非常重要但是對(duì)于自己不是那么關(guān)心的事情,可以利用消息隊(duì)列去做。
支持最終一致性的消息隊(duì)列,能夠用來(lái)處理延遲不那么敏感的“分布式事務(wù)”場(chǎng)景,而且相對(duì)于笨重的分布式事務(wù),可能是更優(yōu)的處理方式。
當(dāng)上下游系統(tǒng)處理能力存在差距的時(shí)候,利用消息隊(duì)列做一個(gè)通用的“漏斗”。在下游有能力處理的時(shí)候,再進(jìn)行分發(fā)。

為什么要選擇RabbitMQ

  1. 基于AMQP協(xié)議
  2. 高并發(fā)
  3. 高性能
  4. 高可用
  5. 強(qiáng)大的社區(qū)支持,以及很多公司都在使用
  6. 支持插件
  7. 支持多語(yǔ)言

AMQP協(xié)議介紹

出現(xiàn)背景

越是大型的公司越是不可避免的使用來(lái)自眾多供應(yīng)商的MQ產(chǎn)品,來(lái)服務(wù)企業(yè)內(nèi)部的不同應(yīng)用。如果應(yīng)用已經(jīng)訂閱了TIBCO MQ信息,若突然需要消費(fèi)來(lái)自IBM MQ的消息,則實(shí)現(xiàn)起來(lái)會(huì)非常困難。這些產(chǎn)品使用不同的api,不同的協(xié)議,因而毫無(wú)疑問(wèn)無(wú)法聯(lián)合起來(lái)組成單一的總線(xiàn)。為了解決這個(gè)問(wèn)題,Java Message Service(JMS)在2001年誕生了。JMS試圖通過(guò)提供公共java api的方式,隱藏單獨(dú)MQ產(chǎn)品供應(yīng)商提供的實(shí)際接口,從而跨越了壁壘和解決了互通問(wèn)題。從技術(shù)上講,java應(yīng)用程序只需要對(duì)JMS API編程,選擇合適的MQ驅(qū)動(dòng)即可。JMS會(huì)打理好其他部分的。問(wèn)題是你在嘗試使用單獨(dú)編準(zhǔn)化接口來(lái)整合眾多不同的接口。這就像是把不同的類(lèi)型的衣服粘在一起:縫合處終究會(huì)裂開(kāi)。使用JMS(Java Message Service)的應(yīng)用程序會(huì)變得更加脆弱。我們需要新的消息通信標(biāo)準(zhǔn)化方案。

  • 高級(jí)消息隊(duì)列協(xié)議(AMQP)是面向消息的中間件的開(kāi)放標(biāo)準(zhǔn)應(yīng)用層協(xié)議。 AMQP的特征是消息導(dǎo)向,排隊(duì),路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布和訂閱),可靠性和安全性。

  • AMQP要求消息傳遞提供商和客戶(hù)端的行為在不同供應(yīng)商實(shí)現(xiàn)可互操作的情況下,以與SMTP,HTTP,F(xiàn)TP等相同的方式創(chuàng)建了可互操作的系統(tǒng)。 中間件的以前標(biāo)準(zhǔn)化發(fā)生在API級(jí)別(例如JMS),并且專(zhuān)注于使程序員與不同中間件實(shí)現(xiàn)的交互標(biāo)準(zhǔn)化,而不是提供多個(gè)實(shí)現(xiàn)之間(AMQP的實(shí)現(xiàn))的互操作性。與定義API和消息傳遞實(shí)現(xiàn)必須提供的一組行為的JMS不同,AMQP是線(xiàn)級(jí)協(xié)議。 線(xiàn)級(jí)協(xié)議是以網(wǎng)絡(luò)流作為字節(jié)流發(fā)送的數(shù)據(jù)格式的描述。 因此,無(wú)論實(shí)現(xiàn)語(yǔ)言如何,任何可以創(chuàng)建和解釋符合此數(shù)據(jù)格式的消息的工具都可以與任何其他兼容工具進(jìn)行互操作。

  • AMQP協(xié)議是具有現(xiàn)代特征的二進(jìn)制協(xié)議。一個(gè)提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)發(fā)標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)?;诖藚f(xié)議的客戶(hù)端與消息中間件可傳遞消息,并不受客戶(hù)端/中間件不同產(chǎn)品,不同開(kāi)發(fā)語(yǔ)言等條件的限制。

  • AMQP是一種二進(jìn)制應(yīng)用層協(xié)議,旨在有效地支持各種消息應(yīng)用和通信模式。 它提供流控制的面向消息的通信,其中包括消息傳遞保證,例如最多一次(每個(gè)消息被投遞一次或從不投遞消息),至少一次(每個(gè)消息肯定要被傳遞,但可以在不同的時(shí)間)和確定一次(其中消息將始終確定到達(dá)并僅執(zhí)行一次),以及基于SASL和/或TLS的身份驗(yàn)證和/或加密。 它假定一個(gè)基本的可靠傳輸層協(xié)議,如傳輸控制協(xié)議(TCP)。

  • AMQP規(guī)范定義在幾個(gè)層次中:(i)類(lèi)型系統(tǒng)(傳遞的消息類(lèi)型),(ii)用于將消息從一個(gè)進(jìn)程轉(zhuǎn)移到另一個(gè)進(jìn)程的對(duì)稱(chēng)異步協(xié)議,(iii)標(biāo)準(zhǔn)的可擴(kuò)展消息格式(iv)一系列的標(biāo)準(zhǔn)化但可擴(kuò)展的“消息傳遞功能”。

一些概念梳理

  • Server:又稱(chēng)為Broker。接收客戶(hù)端連接,實(shí)現(xiàn)AMQP的服務(wù)器實(shí)體。
  • Connection:連接,應(yīng)用程序與Broker的網(wǎng)絡(luò)連接。
  • Channel:信道,幾乎所有的操作都在Channel中進(jìn)行,Channel是進(jìn)行消息讀寫(xiě)的通道??蛻?hù)端可建立多個(gè)Channel,每個(gè)Channel代表一個(gè)會(huì)話(huà)任務(wù)。
  • Message:消息。服務(wù)器和應(yīng)用程序之間傳遞的數(shù)據(jù),本質(zhì)上就是一段數(shù)據(jù),由Properties和Body組成。
  • Exchange:交換機(jī)。接收消息,根據(jù)路由鍵轉(zhuǎn)發(fā)消息到綁定的隊(duì)列。
  • Binding:Exchange和Queue之間的虛擬連接,binding中可以包含routing key。
  • Routing key:一個(gè)虛擬地址,虛擬機(jī)可用它來(lái)確定如何路由一個(gè)特定消息。
  • Queue:也稱(chēng)為Message Queue,消息隊(duì)列,保存消息并將它們轉(zhuǎn)發(fā)給消費(fèi)者。
  • Virtual Host:其實(shí)是一個(gè)虛擬概念。類(lèi)似于權(quán)限控制組,一個(gè)Virtual Host里面可以有若干個(gè)Exchange和Queue,可以用來(lái)隔離Exchange和Queue。,同一個(gè)Virtual Host里面不能有相同名稱(chēng)的Exchange和Queue。但是權(quán)限控制的最小粒度是Virtual Host。(下面會(huì)講到)
AMQP協(xié)議模型

總結(jié)
生產(chǎn)者將消息發(fā)送到Exchange交換機(jī)的,不是發(fā)送到Queue上的,生產(chǎn)者不知道消息是誰(shuí)消費(fèi),有哪些消費(fèi)者消費(fèi)。Exchange根據(jù)一定的路由規(guī)則將消息轉(zhuǎn)發(fā)到Queue。
消費(fèi)者是監(jiān)聽(tīng)隊(duì)列的,不知道是哪個(gè)生產(chǎn)者發(fā)送的。

AMQP我的理解
一個(gè)開(kāi)放的面向消息中間件的協(xié)議,所有此協(xié)議的實(shí)現(xiàn)可以進(jìn)行互相操作,無(wú)論實(shí)現(xiàn)語(yǔ)言如何,任何符合此協(xié)議的數(shù)據(jù)格式的消息工具都可以與任何其他兼容工具進(jìn)行互操作。而以前JMS(Java Message Service),將不同的中間件的實(shí)現(xiàn)進(jìn)行API層次的標(biāo)準(zhǔn)化。

AMQP實(shí)現(xiàn)

RabbitMQ
Apache Qpid
OpenAMQ

參考資料
消息中間件設(shè)計(jì)精要
RabbitMQ博客
githut地址

AMQP參考資料
amqp官網(wǎng)
amqp官網(wǎng)協(xié)議下載
amqp協(xié)議文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 歷史 RabbitMQ是一個(gè)由erlang開(kāi)發(fā)的AMQP(Advanced Message Queue )的...
    高廣超閱讀 6,236評(píng)論 3 51
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,586評(píng)論 19 139
  • 一、 消息隊(duì)列概述 消息隊(duì)列中間件是分布式系統(tǒng)中重要的組件,主要解決應(yīng)用耦合、異步消息、流量削鋒等問(wèn)題。實(shí)現(xiàn)高性能...
    步積閱讀 57,443評(píng)論 10 138
  • 來(lái)源 RabbitMQ是用Erlang實(shí)現(xiàn)的一個(gè)高并發(fā)高可靠AMQP消息隊(duì)列服務(wù)器。支持消息的持久化、事務(wù)、擁塞控...
    jiangmo閱讀 10,513評(píng)論 2 34
  • 1.什么是消息隊(duì)列 消息隊(duì)列允許應(yīng)用間通過(guò)消息的發(fā)送與接收的方式進(jìn)行通信,當(dāng)消息接收方服務(wù)忙或不可用時(shí),其提供了一...
    zhuke閱讀 4,631評(píng)論 0 12

友情鏈接更多精彩內(nèi)容