本文將介紹一些使用Qpid需要了解的基礎(chǔ)概念,不涉及Qpid的性能、安全、高可用、API等。包含的內(nèi)容如下:
- Qpid的定義
- Broker
- 安裝與啟動(dòng)
- Web管理界面
- Qpid的幾個(gè)組成部分的概念
- 介紹Broker內(nèi)的Exchange與Queue
- 參考資料
QPID是一種實(shí)現(xiàn)AMQP協(xié)議的消息隊(duì)列
AMQP是一種用于業(yè)務(wù)消息的開(kāi)放網(wǎng)絡(luò)協(xié)議。他定義了一種允許雙方進(jìn)行可靠業(yè)務(wù)消息傳遞的二進(jìn)制線級(jí)協(xié)議。該協(xié)議的目標(biāo)是成為所有消息中間件之間進(jìn)行互操作的標(biāo)準(zhǔn)協(xié)議。
消息隊(duì)列是一種進(jìn)程間通信線程或同一進(jìn)程的不同線程間的通信方式。
Qpid則是由Apache開(kāi)發(fā)的一種消息隊(duì)列,實(shí)現(xiàn)了AMQP協(xié)議,并且支持多種語(yǔ)言與多種平臺(tái)。
Qpid采用Broker架構(gòu)
Qpid提供了一個(gè)服務(wù)端(即Broker),我們自己實(shí)現(xiàn)的各個(gè)單獨(dú)的業(yè)務(wù)模塊進(jìn)行通訊時(shí),發(fā)送的消息需要先經(jīng)過(guò)Broker。Qpid實(shí)現(xiàn)了兩種Broker,一種采用Java語(yǔ)言實(shí)現(xiàn),一種采用C++語(yǔ)言實(shí)現(xiàn),兩者實(shí)現(xiàn)的特性是不同的,如Java版的Broker支持的AMQP版本為 0-10,0-9-1,0-9,0-8和1.0,而C++版的Broker僅支持1.0和0-10版本的AMQP,具體的差別需要查看官方文檔,本文僅僅針對(duì)Java版的Broker進(jìn)行說(shuō)明演示。
Broker的安裝與啟動(dòng)
此處以運(yùn)行在Windows系統(tǒng)下的Java版Broker為例,Linux版的可參考官方文檔
下載
在該頁(yè)面內(nèi)下載Brokerhttps://qpid.apache.org/download.html
安裝
解壓下載的Broker安裝包即可
設(shè)置工作目錄
在Windows系統(tǒng)內(nèi)設(shè)置系統(tǒng)變量 QPID_WORK。
setx QPID_WORK Broker的安裝目錄/work /m
在工作目錄中,默認(rèn)存儲(chǔ)著需要持久化的消息和Broker的日志文件,還包括一些配置文件。
執(zhí)行啟動(dòng)腳本,啟動(dòng)Broker
在bin目錄內(nèi)執(zhí)行qpid-server.bat腳本,即可啟動(dòng)Broker。

Web管理界面
Qpid一般可以通過(guò)Web界面、REST API等方式進(jìn)行管理,下面主要介紹Web管理界面。
Qpid提供了一個(gè)Web管理界面,提供了添加Exchange、Queue以及將Queue綁定到Exchange上等功能。Qpid大多數(shù)的管理操作都可以在這個(gè)Web管理界面完成。
管理界面的端口默認(rèn)為8080。在Broker所在的操作系統(tǒng)內(nèi)打開(kāi)瀏覽器,輸入網(wǎng)址localhost:8080即可打開(kāi)管理界面的登錄頁(yè)面。使用用戶名admin,密碼admin,即可登錄。
在管理界面的左邊有一顆樹(shù),樹(shù)的根為Broker,其子節(jié)點(diǎn)分別為brokerloggers、virtualhostnodes、ports、authenticationproviders、plugins。每個(gè)節(jié)點(diǎn)及其下子節(jié)點(diǎn)等都可以嘗試雙擊下,如果可以在界面右邊打開(kāi)一個(gè)標(biāo)簽頁(yè),那么就可以針對(duì)這個(gè)節(jié)點(diǎn)進(jìn)行一些設(shè)置。
brokerloggers
Qpid可以有多個(gè)logger,用于配置Qpid的日志打印。Qpid提供了多種類型的logger供用戶使用。默認(rèn)情況下則提供了名字為memory和名字為logfile的兩個(gè)logger。memory的類型為Memory。Memory類型的logger默認(rèn)在內(nèi)存中保存最近的4096條日志事件,用戶可以通過(guò)web管理界面查看保存的日志。logfile的類型為File。File類型的logger會(huì)將日志寫(xiě)入到磁盤文件中,用戶可以配置日志文件的路徑、名稱、打印日志的樣式、打印的日志級(jí)別、如何進(jìn)行rolling等。如果對(duì)log4j等日志框架的使用,那么對(duì)于File類型的logger應(yīng)該不會(huì)太陌生,這里不再敖述。關(guān)于日志的更多信息可參考這里
virtualhostnodes
virtualhostnodes節(jié)點(diǎn)內(nèi)可以有多個(gè)virtualhostnode,每個(gè)virtualhostnode只有一個(gè)virtualhost,而virtualhost內(nèi)有多個(gè)exchange與queue;virtualhostnode與virtualhost各自多種類型,基本與其使用的存儲(chǔ)和HA有關(guān),如Derby,BDB類型等。
默認(rèn)情況下,qpid創(chuàng)建了一個(gè)名字為default的virtualhostnode和一個(gè)名字為default的virtualhost。名字為default的virtualhostnode的類型為JSON,名字為default的virtualhost類型是DERBY。
ports
Qpid的port與平常理解的端口不同,這里定義的是使用協(xié)議進(jìn)行消息傳輸和管理Qpid。Qpid默認(rèn)提供了名字為HTTP和名字為AMQP的port,名字為HTTP的port的類型是HTTP,名字為AMQP的port類型是AMQP。Qpid通過(guò)HTTP類型的port進(jìn)行Qpid的管理,如添加刪除queue,通過(guò)AMQP類型的port進(jìn)行消息的傳輸。從名字可以看出,HTTP類型的port使用的是http協(xié)議,AMQP類型的port使用的是amqp協(xié)議。
| 名字 | port類型 | 協(xié)議 | 作用 | Authentication Provider |
|---|---|---|---|---|
| HTTP | HTTP | http | 用于通過(guò)http協(xié)議管理Qpid | passwordFile |
| AMQP | AMQP | amqp | 用于通過(guò)amqp協(xié)議傳輸消息 | passwordFile |
authenticationproviders
Authentication Provider用于port進(jìn)行連接的認(rèn)證。Qpid默認(rèn)提供一個(gè)名字為passwordFile的Authentication Provider,類型為PlainPasswordFile。PlainPasswordFile根據(jù)本地文件中純文本中存儲(chǔ)的用戶賬號(hào)密碼驗(yàn)證用戶,該文本文件的格式為:
用戶名:密碼
passwordFile設(shè)置了該文本文件為Qpid安裝目錄下的文件夾etc下的passwd文件,內(nèi)容為
guest:guest
client:guest
server:guest
admin:admin
webadmin:webadmin
每個(gè)port只能設(shè)置一個(gè)Authentication Provider。Qpid提供的兩個(gè)port(HTTP和AMQP)默認(rèn)都使用了passwordFile。所以我們?cè)诘卿沇eb管理界面和進(jìn)行消息傳輸時(shí),可以使用guest、clent、server、admin、webadmin進(jìn)行登錄,其密碼分別對(duì)應(yīng)為guest、guest、guest、admin、webadmin。
Qpid提供的Authentication Provider的類型包括:Anonymous、External、Kerberos、SimpleLDAP、OAuth2、ScramSha、Plain、PlainPasswordFile、MD5、Base64MD5PasswordFile
其中Anonymous是最簡(jiǎn)單的,它的作用是不對(duì)連接做任何認(rèn)證。如果把Qpid的HTTP(port)的Authentication Provider設(shè)置為Anonymous類型,那么我們無(wú)需經(jīng)過(guò)登錄頁(yè)面輸入用戶密碼即可進(jìn)入管理頁(yè)面。
plugins
該節(jié)點(diǎn)下默認(rèn)有兩個(gè)插件,httpManagement和jmxManagement。
MANAGEMENT-HTTP類型的httpManagement,現(xiàn)在使用的Web管理界面以及REST API由httpManagement這個(gè)插件提供。jmxManagement與jmx相關(guān),最新版的文檔沒(méi)有找到這方面的信息,6.4. JMX Management這是一份舊的文檔,有需要可以參考。
Broker的Exchange、Queue
Exchange和Queue是Broker的兩個(gè)重要部分。Exchange用于接收消息發(fā)送者的消息,并根據(jù)其自身的路由算法、綁定表、消息中的一些屬性,將消息路由到對(duì)應(yīng)的Queue中;Queue用于存儲(chǔ)消息,消息消費(fèi)者需通過(guò)Queue獲取消息。各個(gè)Queue與各個(gè)Exchange通過(guò)綁定表進(jìn)行綁定,Exchange的綁定表的內(nèi)容包括Queue、Binding key、Arguments。當(dāng)消息到達(dá)Exchange時(shí),在不考慮Arguments的情況下,如果Binding key會(huì)與消息中的Routing key(Routing key實(shí)際指消息中屬性qpid.subject的值)匹配成功,則消息會(huì)發(fā)給綁定表內(nèi)對(duì)應(yīng)的Queue。
Exchange的類型:Direct,Topic,Fanout,Headers
Broker提供了4種類型的Exchange,不同類型的Exchange,實(shí)現(xiàn)的路由算法不同。初始啟動(dòng)Broker服務(wù)器時(shí),Qpid會(huì)預(yù)先在Broker中創(chuàng)建4個(gè)Exchange,名字分別為
- amq.direct (類型為direct)
- amq.topic (類型為topic)
- amq.fanout (類型為fanout)
- amq.match (類型為headers)
以下討論的Topic、Direct、Fanout不考慮綁定表中的Arguments對(duì)消息的影響。Topic、Direct、Fanout都支持Arguments中的JMS message selector,具體使用方法可參考 binding argument specifying a JMS message selector和How to use Message Selectors to filter messages。Headers不支持JMS message selector。
Topic
一般用于發(fā)布/訂閱模式的消息模式。
該類型Exchange的綁定表的binding key支持精確匹配和通配符匹配,其中 * 代表一個(gè)單詞, # 代表零個(gè)或者多個(gè)單詞,單詞與單詞之間以 . 分隔。
Topic的精確匹配

消息生產(chǎn)者將消息發(fā)送到amq.topic,消息的routing_key與綁定表的binding_key都相等,則將消息路由至隊(duì)列sub1、sub2、sub3。
Topic的通配符匹配

紅色消息的routing_key為news.uk,即兩個(gè)單詞news和uk。查看綁定表,第一個(gè)binding_key匹配news和零個(gè)或者多個(gè)單詞,匹配成功,消息會(huì)發(fā)送至隊(duì)列sub1;第二個(gè)binding_key匹配news和uk,匹配成功,消息會(huì)發(fā)送至隊(duì)列sub2;第三個(gè)binding_key匹配一個(gè)單詞加uk,匹配成功,消息會(huì)發(fā)送至隊(duì)列sub3。綠色消息只匹配了第一個(gè)binding_key,會(huì)發(fā)送至sub1。藍(lán)色隊(duì)列匹配第三個(gè)binding_key,會(huì)發(fā)送至sub3。黃色隊(duì)列沒(méi)有匹配成功,此時(shí)qpid的處理方式會(huì)根據(jù)協(xié)議版本和設(shè)置的不同有所不同,一般是直接丟棄消息。
Direct
一般用于點(diǎn)對(duì)點(diǎn)的模式。與Topic不同的是Direct類型的Exchange的綁定表的binding key只支持精確匹配。

如圖所示,黃色消息的routing_key的值與綁定表中第一條記錄的binding_key相等,則黃色消息會(huì)傳遞到隊(duì)列myqueue;紅色消息的的routing_key的值與綁定表中第二條和第三條記錄的binding_key相等,則紅色消息會(huì)傳遞到隊(duì)列bar1和bar2內(nèi);藍(lán)色消息的routing_key消息與綁定表無(wú)法匹配,此時(shí)qpid的處理方式會(huì)根據(jù)協(xié)議版本和設(shè)置的不同有所不同,一般是直接丟棄消息。
Fanout
一般用于廣播模式。綁定表的binding_key不生效,發(fā)送至該類型Exchange的消息直接發(fā)送至綁定表內(nèi)的隊(duì)列。

Headers
Headers的作用是支持Arguments中設(shè)置的x-match。具體使用方法,參考 x-match expression。Headers不支持JMS message selector。
Queue的類型
支持4中類型:
Standard - 一個(gè)簡(jiǎn)單的先進(jìn)先出隊(duì)列。
Priority - 每個(gè)消息的priority決定消息的傳輸順序。
注意如果在創(chuàng)建該類型隊(duì)列時(shí),設(shè)置Priorities屬性的值為0,則Broker服務(wù)端進(jìn)程進(jìn)行會(huì)拋數(shù)組越界異常,直接退出。退出后手動(dòng)可以啟動(dòng),但如果對(duì)qpid進(jìn)行操作也會(huì)導(dǎo)致Broker服務(wù)端進(jìn)程退出。在采用Qpid JMS (AMQP 0-10)的setJMSPriority(int priority)設(shè)置消息優(yōu)先級(jí)并發(fā)送至隊(duì)列時(shí),消息隊(duì)列內(nèi)接收到的消息的優(yōu)先級(jí)依舊是默認(rèn)的優(yōu)先級(jí)4,暫時(shí)不知道是什么原因引起這種情況。
Sorted - 傳輸順序依賴于在消息中的排序鍵屬性。
例如設(shè)置queue的qpid.queue_sort_key的值為testSortedKey,設(shè)置5條消息的屬性testSortedKey的值分別為字符'5','4','1','6','7',并將消息發(fā)送至Sorted類型的隊(duì)列,則之后消費(fèi)者消費(fèi)消息時(shí)的順序是'1','4','5','6','7'。
Last Value Queue - 該隊(duì)列只保存包含指定的LVQ key值的最新的一條消息。但是未包含指定LVQ key值的消息正常存儲(chǔ)在隊(duì)列上。
參考資料
維基百科:Advanced Message Queuing Protocol
AMQP官網(wǎng)
AMQP協(xié)議規(guī)范文檔下載
Apache Qpid Broker for Java
How to use Message Selectors to filter messages