RabbitMQ的 AMQP協(xié)議都是些什么內(nèi)容呢
阿粉之前也講述過關(guān)于 RabbitMQ 的相關(guān)內(nèi)容,比如他們的配置,以及 RabbitMQ 整合 SpringBoot 使用,而且自己使用過之后,就會在自己的簡歷上面寫上自己使用 RabbitMQ 實現(xiàn)了什么功能,但是這就會導(dǎo)致,有些面試官就會問一些關(guān)于 RabbitMQ 的一些相關(guān)的問題,比如, RabbitMQ 中的交換機是什么, RabbitMQ 中的路由都有哪些?
反正諸如此類的問題,都是屬于相對簡單的問題,但是也不排除會有一些相對高級一點的問題,就比如接下來的關(guān)于 RabbitMQ 的協(xié)議的問題。
AMQP 協(xié)議
AMQP(高級消息隊列協(xié)議)是一個網(wǎng)絡(luò)協(xié)議。它支持符合要求的客戶端應(yīng)用(application)和消息中間件代理(messaging middleware broker)之間進(jìn)行通信。
消息代理(message brokers)從發(fā)布者(publishers)亦稱生產(chǎn)者(producers)那兒接收消息,并根據(jù)既定的路由規(guī)則把接收到的消息發(fā)送給處理消息的消費者(consumers)。
由于AMQP是一個網(wǎng)絡(luò)協(xié)議,所以這個過程中的發(fā)布者,消費者,消息代理 可以存在于不同的設(shè)備上。
這就是使用消息隊列最好的地方,消息的發(fā)布者,也就是生產(chǎn)者和消息費可以不在相同的設(shè)備上,但是可以保持通信。
AMQP協(xié)議是一個二進(jìn)制協(xié)議,擁有一些現(xiàn)代特點:多信道、協(xié)商式、異步、安全、跨平臺、中立、高效。
AMQP通常被劃分為三層:
模型層定義了一套命令(按功能分類),客戶端應(yīng)用可以利用這些命令來實現(xiàn)它的業(yè)務(wù)功能。
會話層負(fù)責(zé)將命令從客戶端應(yīng)用傳遞給服務(wù)器,再將服務(wù)器的應(yīng)答傳遞給客戶端應(yīng)用,會話層為這個傳遞過程提供可靠性、同步機制和錯誤處理。
傳輸層提供幀處理、信道復(fù)用、錯誤檢測和數(shù)據(jù)表示。
實現(xiàn)者可以將傳輸層替換成任意傳輸協(xié)議,只要不改變AMQP協(xié)議中與客戶端應(yīng)用程序相關(guān)的功能。實現(xiàn)者還可以使用其他高層協(xié)議中的會話層。
如果你要是去百度上所有 AMQP 反正各大博主上來就說 AMQP 0-9-1 ,但是也不說 這個 0-9-1 到底是什么意思,反正都是書中找的,直接介紹就完事。
這個東西,阿粉專門找了一些書籍,才了解這個東西指的是什么。
實際上 AMQP 后面所攜帶的 0-9-1 指的是他的版本號,主版本號和次版本號。我們約定版本由主版本號后面加小數(shù)點再加上次版本號組成(比如1-3表示主版本號為1,次版本號為3)。
主版本號保持不變,次版本號遞增。當(dāng)AMQP工作組提升主版本號時,次版本號將被設(shè)置為0。因此,有可能出現(xiàn)這樣的版本序列:1-2,1-3,1-4,2-0,2-1……
旦本協(xié)議發(fā)布之后(主版本號大于1),應(yīng)盡量防止次版本號遞增到9。不過在發(fā)布之前(版本0-x),由于會對本協(xié)議進(jìn)行頻繁的修訂,可以不遵守這條約定。
而這也是大家在百度上所有 AMQP 協(xié)議中的 AMQP 0-9-1 的由來。
AMQP 模型
一個由關(guān)鍵實體和語義表示的邏輯框架,遵從AMQP規(guī)范的服務(wù)器必須提供這些實體和語義。為了實現(xiàn)本規(guī)范中定義的語義,客戶端可以發(fā)送命令來控制AMQP服務(wù)器。
實際上這個就是一個工作過程的簡介。
消息的生產(chǎn)者,將消息發(fā)送到交換機,然后交換機收到消息之后,根據(jù)不同的路由規(guī)則,發(fā)給綁定的隊列,最后 AMQP 代理會將消息投遞給訂閱了此隊列的消費者,或者消費者按照需求自行獲取。
也就是從 product ->exchange -> queue ->consumer
其實 AMQP 也是一個可編程的協(xié)議。
可編程協(xié)議是什么?
某種意義上說AMQP的實體和路由規(guī)則是由應(yīng)用本身定義的,而不是由消息代理定義。包括像聲明隊列和交換機,定義他們之間的綁定,訂閱隊列等等關(guān)于協(xié)議本身的操作。
這雖然能讓開發(fā)人員自由發(fā)揮,但也需要他們注意潛在的定義沖突。當(dāng)然這在實踐中很少會發(fā)生,如果發(fā)生,會以配置錯誤(misconfiguration)的形式表現(xiàn)出來。
應(yīng)用程序(Applications)聲明AMQP實體,定義需要的路由方案,或者刪除不再需要的AMQP實體。
至于 RabbitMQ 中的 隊列,交換機,后還有路由啥的,阿粉就不說了,那個東西自己理解反而比別人說的有效。
唯一需要注意的是, 當(dāng)一條消息發(fā)布的時候,發(fā)布者可能會指定一些消息屬性message attributes(也叫message meta-data消息元數(shù)據(jù)),其中有一些消息屬性是用于消息中間件處理消息,其余的部分則是用于消息消費者對于消息中間件完全透明。
由于網(wǎng)絡(luò)的不穩(wěn)定性,消息在傳輸過程中可能出現(xiàn)失敗的情況,鑒于此AMQP 0-9-1提供了一種消息確認(rèn)機制message acknowledgements: 當(dāng)一條消息傳遞給消費者后該消費者發(fā)送一條通知notifies給消息中間件來確認(rèn)消息,無論是自動的還是開發(fā)者自己這樣做,當(dāng)消息確認(rèn)機制使用時,只有當(dāng)消息代理收到通知后才會將該條或該組消息從消息隊列中移除。
在一些特定情況下,比如當(dāng)消息不能被路由時,消息可能會被返回給消息發(fā)布者,或者刪除,或者如果消息代理實現(xiàn)了某種擴(kuò)展插件,則這些無法被路由的消息可能會被放入一個稱之為dead letter queue(死亡標(biāo)記隊列)的隊列中,發(fā)布者可以通過指定一些確定的消息屬性 message attributes來響應(yīng)出現(xiàn)這種情景時消息應(yīng)該如何被處理。