AMQP,即Advanced Message Queuing Protocol,高級消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個開放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。
當(dāng)
前各種應(yīng)用大量使用異步消息模型,并隨之產(chǎn)生眾多消息中間件產(chǎn)品及協(xié)議,標(biāo)準(zhǔn)的不一致使應(yīng)用與中間件之間的耦合限制產(chǎn)品的選擇,并增加維護(hù)成本。AMQP
是一個提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)協(xié)議,基于此協(xié)議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件不同產(chǎn)品,不同開發(fā)語言等條件的限制。
AMQP的主要特征是面向消息、隊(duì)列、路由(包括點(diǎn)對點(diǎn)和發(fā)布/訂閱)、可靠性、安全。
AMQP在消息提供者和客戶端的行為進(jìn)行了強(qiáng)制規(guī)定,使得不同賣商之間真正實(shí)現(xiàn)了互操作能力。
JMS是早期消息中間件進(jìn)行標(biāo)準(zhǔn)化的一個嘗試,它僅僅是在API級進(jìn)行了規(guī)范,離創(chuàng)建互操作能力還差很遠(yuǎn)。
與JMS不同,AMQP是一個Wire級的協(xié)議,它描述了在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)的格式,以字節(jié)為流。因此任何遵守此數(shù)據(jù)格式的工具,其創(chuàng)建和解釋消息,都能與其他兼容工具進(jìn)行互操作。
AMQP規(guī)范的版本:
0-8 是2006年6月發(fā)布
0-9 于2006年12月發(fā)布
0-9-1 于2008年11月發(fā)布
0-10 于2009年下半年發(fā)布
1.0 draft (文檔還是草案)
AMQP的實(shí)現(xiàn)有:
1)OpenAMQ
AMQP的開源實(shí)現(xiàn),用C語言編寫,運(yùn)行于Linux、AIX、Solaris、Windows、OpenVMS。
2)Apache Qpid
Apache的開源項(xiàng)目,支持C++、Ruby、Java、JMS、Python和.NET。
3)Redhat Enterprise MRG
實(shí)現(xiàn)了AMQP的最新版本0-10,提供了豐富的特征集,比如完全管理、聯(lián)合、Active-Active集群,有Web控制臺,還有許多企業(yè)級特征,客戶端支持C++、Ruby、Java、JMS、Python和.NET。
4)RabbitMQ
一個獨(dú)立的開源實(shí)現(xiàn),服務(wù)器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。RabbitMQ發(fā)布在Ubuntu、FreeBSD平臺。
5)AMQP Infrastructure
Linux下,包括Broker、管理工具、Agent和客戶端。
6)?MQ
一個高性能的消息平臺,在分布式消息網(wǎng)絡(luò)可作為兼容AMQP的Broker節(jié)點(diǎn),綁定了多種語言,包括Python、C、C++、Lisp、Ruby等。
7)Zyre
是一個Broker,實(shí)現(xiàn)了RestMS協(xié)議和AMQP協(xié)議,提供了RESTful HTTP訪問網(wǎng)絡(luò)AMQP的能力。
AMQP所提供的域模型。
消息中間件的主要功能是消息的路由(Routing)和緩存(Buffering)。在AMQP中提供類似功能的兩種域模型:Exchange 和 Message queue。
Exchange接收消息生產(chǎn)者(Message Producer)發(fā)送的消息根據(jù)不同的路由算法將消息發(fā)送往Message queue。Message queue會在消息不能被正常消費(fèi)時(shí)緩存這些消息,具體的緩存策略由實(shí)現(xiàn)者決定,當(dāng)message queue與消息消費(fèi)者(Message consumer)之間的連接通暢時(shí),Message queue有將消息轉(zhuǎn)發(fā)到consumer的責(zé)任。
Message是當(dāng)前模型中所操縱的基本單位,它由Producer產(chǎn)生,經(jīng)過Broker被Consumer所消費(fèi)。它的基本結(jié)構(gòu)有兩部分:
Header和Body。Header是由Producer添加上的各種屬性的集合,這些屬性有控制Message是否可被緩存,接收的queue是哪
個,優(yōu)先級是多少等。Body是真正需要傳送的數(shù)據(jù),它是對Broker不可見的二進(jìn)制數(shù)據(jù)流,在傳輸過程中不應(yīng)該受到影響。
一個broker中會存在多個Message queue,Exchange怎樣知道它要把消息發(fā)送到哪個Message queue中去呢? 這就是上圖中所展示Binding的作用。Message
queue的創(chuàng)建是由client application控制的,在創(chuàng)建Message
queue后需要確定它來接收并保存哪個Exchange路由的結(jié)果。Binding是用來關(guān)聯(lián)Exchange與Message
queue的域模型。Client application控制Exchange與某個特定Message
queue關(guān)聯(lián),并將這個queue接受哪種消息的條件綁定到Exchange,這個條件也叫Binding key 或是 Criteria。
在與多個Message queue關(guān)聯(lián)后,Exchange中就會存在一個路由表,這個表中存儲著每個Message queue所需要消息的限制條件。Exchange就會檢查它接受到的每個Message的Header及Body信息,來決定將Message路由到哪個queue中去。Message
的Header中應(yīng)該有個屬性叫Routing
Key,它由Message發(fā)送者產(chǎn)生,提供給Exchange路由這條Message的標(biāo)準(zhǔn)。Exchange根據(jù)不同路由算法有不同有
Exchange Type。比如有Direct類似,需要Binding key 等于Routing key;也有Binding
key與Routing key符合一個模式關(guān)系;也有根據(jù)Message包含的某些屬性來判斷。一些基礎(chǔ)的路由算法由AMQP所提供,client
application也可以自定義各種自己的擴(kuò)展路由算法。
那么一個Message的處理流程類似于這樣:
在這里有個新名詞需要介紹: Virtual Host。一個Virtual Host可持有一些Exchange和Message queue。它是一個虛擬概念,一個Virtual Host可以是一臺服務(wù)器,也可以是由多臺服務(wù)器組成的集群。同步擴(kuò)展下,Exchange與Message queue的部署也可以是一臺或是多臺服務(wù)器上。
Message的產(chǎn)生者和消費(fèi)者可能是同一個應(yīng)用。整個AMQP定義的就是Client application與Broker之間的交互。在粗略介紹完AMQP的域模型后,可以關(guān)注下Client是怎樣與Broker建立起連接的。
在AMQP中,Client application想要與Broker溝通,就需要建立起與Broker的connection,這種connection其實(shí)是與Virtual Host相關(guān)聯(lián)的,也就是說,connection是建立在client與Virtual Host之間。可以在一個connection上并發(fā)運(yùn)行多個channel,每個channel執(zhí)行與Broker的通信,我們前面提供的session就是依附于channel上的。
這里的Session可以有多種定義,既可以表示AMQP內(nèi)部提供的command分發(fā)機(jī)制,也可以說是在宏觀上區(qū)別與域模型的接口。正常理解就是我們平
時(shí)所說的交互context,主要作用就是在網(wǎng)絡(luò)上可靠地傳遞每一個command。在AMQP的設(shè)計(jì)中,應(yīng)當(dāng)是借鑒了TCP的各種設(shè)計(jì),用于保證這種可
靠性。
在Session層,為上層所需要交互的每個command分配一個惟一標(biāo)識符(可以是一個UUID),是為了在傳輸過程中可以對command做校驗(yàn)和
重傳。Command發(fā)送端也需要記錄每個發(fā)送出去的command到Replay Buffer,以期得到接收方的回饋,保證
這個command被接收方明確地接收或是已執(zhí)行這個command。對于超時(shí)沒有收到反饋的command,發(fā)送方再次重傳。如果接收方已明確地回饋信
息想要告知command發(fā)送方但這條信息在中途丟失或是其它問題發(fā)送方?jīng)]有收到,那么發(fā)送方不斷重傳會對接收方產(chǎn)生影響,為了降低這種影
響,command接收方設(shè)置一個過濾器Idempotency Barrier,來攔截那些已接收過的command。
關(guān)于這種重傳及確認(rèn)機(jī)制,可以參考下TCP的相關(guān)設(shè)計(jì)。









