天天看點

RabbitMQ(一):RabbitMQ快速入門

RabbitMQ是目前非常熱門的一款消息中間件,不管是網際網路大廠還是中小企業都在大量使用。作為一名合格的開發者,有必要對RabbitMQ有所了解,本文是RabbitMQ快速入門文章,主要内容包括RabbitMQ是什麼、RabbitMQ核心概念、常用交換器類型、用Docker安裝RabbitMQ等。

以熟悉的電商場景為例,如果商品服務和訂單服務是兩個不同的微服務,在下單的過程中訂單服務需要調用商品服務進行扣庫存操作。按照傳統的方式,下單過程要等到調用完畢之後才能傳回下單成功,如果網絡産生波動等原因使得商品服務扣庫存延遲或者失敗,會帶來較差的使用者體驗,如果在高并發的場景下,這樣的處理顯然是不合适的,那怎麼進行優化呢?這就需要消息隊列登場了。

消息隊列提供一個異步通信機制,消息的發送者不必一直等待到消息被成功處理才傳回,而是立即傳回。消息中間件負責處理網絡通信,如果網絡連接配接不可用,消息被暫存于隊列當中,當網絡暢通的時候在将消息轉發給相應的應用程式或者服務,當然前提是這些服務訂閱了該隊列。如果在商品服務和訂單服務之間使用消息中間件,既可以提高并發量,又降低服務之間的耦合度。

RabbitMQ就是這樣一款我們苦苦追尋的消息隊列。RabbitMQ是一個開源的消息代理的隊列伺服器,用來通過普通協定在完全不同的應用之間共享資料。

RabbitMQ是使用Erlang語言來編寫的,并且RabbitMQ是基于AMQP協定的。Erlang語言在資料互動方面性能優秀,有着和原生Socket一樣的延遲,這也是RabbitMQ高性能的原因所在。可謂“人如其名”,RabbitMQ像兔子一樣迅速。

RabbitMQ(一):RabbitMQ快速入門

RabbitMQ除了像兔子一樣跑的很快以外,還有這些特點:

開源、性能優秀,穩定性保障

提供可靠性消息投遞模式、傳回模式

與Spring AMQP完美整合,API豐富

叢集模式豐富,表達式配置,HA模式,鏡像隊列模型

保證資料不丢失的前提做到高可靠性、可用性

MQ典型應用場景:

異步處理。把消息放入消息中間件中,等到需要的時候再去處理。

流量削峰。例如秒殺活動,在短時間内通路量急劇增加,使用消息隊列,當消息隊列滿了就拒絕響應,跳轉到錯誤頁面,這樣就可以使得系統不會因為超負載而崩潰。

日志處理

應用解耦。假設某個服務A需要給許多個服務(B、C、D)發送消息,當某個服務(例如B)不需要發送消息了,服務A需要改代碼再次部署;當新加入一個服務(服務E)需要服務A的消息的時候,也需要改代碼重新部署;另外服務A也要考慮其他服務挂掉,沒有收到消息怎麼辦?要不要重新發送呢?是不是很麻煩,使用MQ釋出訂閱模式,服務A隻生産消息發送到MQ,B、C、D從MQ中讀取消息,需要A的消息就訂閱,不需要了就取消訂閱,服務A不再操心其他的事情,使用這種方式可以降低服務或者系統之間的耦合。

提到RabbitMQ,就不得不提AMQP協定。AMQP協定是具有現代特征的二進制協定。是一個提供統一消息服務的應用層标準進階消息隊列協定,是應用層協定的一個開放标準,為面向消息的中間件設計。

先了解一下AMQP協定中間的幾個重要概念:

Server:接收用戶端的連接配接,實作AMQP實體服務。

Connection:連接配接,應用程式與Server的網絡連接配接,TCP連接配接。

Channel:信道,消息讀寫等操作在信道中進行。用戶端可以建立多個信道,每個信道代表一個會話任務。

Message:消息,應用程式和伺服器之間傳送的資料,消息可以非常簡單,也可以很複雜。有Properties和Body組成。Properties為外包裝,可以對消息進行修飾,比如消息的優先級、延遲等進階特性;Body就是消息體内容。

Virtual Host:虛拟主機,用于邏輯隔離。一個虛拟主機裡面可以有若幹個Exchange和Queue,同一個虛拟主機裡面不能有相同名稱的Exchange或Queue。

Exchange:交換器,接收消息,按照路由規則将消息路由到一個或者多個隊列。如果路由不到,或者傳回給生産者,或者直接丢棄。RabbitMQ常用的交換器常用類型有direct、topic、fanout、headers四種,後面詳細介紹。

Binding:綁定,交換器和消息隊列之間的虛拟連接配接,綁定中可以包含一個或者多個RoutingKey。

RoutingKey:路由鍵,生産者将消息發送給交換器的時候,會發送一個RoutingKey,用來指定路由規則,這樣交換器就知道把消息發送到哪個隊列。路由鍵通常為一個“.”分割的字元串,例如“com.rabbitmq”。

Queue:消息隊列,用來儲存消息,供消費者消費。

我們完全可以直接使用 Connection 就能完成信道的工作,為什麼還要引入信道呢?
試想這樣一個場景, 一個應用程式中有很多個線程需要從 RabbitMQ 中消費消息,或者生産消息,那麼必然需要建立很多個 Connection,也就是許多個 TCP 連接配接。然而對于作業系統而言,建立和銷毀 TCP 連接配接是非常昂貴的開銷,如果遇到使用高峰,性能瓶頸也随之顯現。 RabbitMQ 采用 TCP 連接配接複用的方式,不僅可以減少性能開銷,同時也便于管理 。

下圖是AMQP的協定模型:

RabbitMQ(一):RabbitMQ快速入門

正如圖中所看到的,AMQP協定模型有三部分組成:生産者、消費者和服務端。

生産者是投遞消息的一方,首先連接配接到Server,建立一個連接配接,開啟一個信道;然後生産者聲明交換器和隊列,設定相關屬性,并通過路由鍵将交換器和隊列進行綁定。同理,消費者也需要進行建立連接配接,開啟信道等操作,便于接收消息。

接着生産者就可以發送消息,發送到服務端中的虛拟主機,虛拟主機中的交換器根據路由鍵選擇路由規則,然後發送到不同的消息隊列中,這樣訂閱了消息隊列的消費者就可以擷取到消息,進行消費。

最後還要關閉信道和連接配接。

RabbitMQ是基于AMQP協定實作的,其結構如下圖所示,和AMQP協定簡直就是一模一樣。

RabbitMQ(一):RabbitMQ快速入門

RabbitMQ常用的交換器類型有direct、topic、fanout、headers四種。

Direct Exchange

該類型的交換器将所有發送到該交換器的消息被轉發到RoutingKey指定的隊列中,也就是說路由到BindingKey和RoutingKey完全比對的隊列中。

RabbitMQ(一):RabbitMQ快速入門

Topic Exchange

該類型的交換器将所有發送到Topic Exchange的消息被轉發到所有RoutingKey中指定的Topic的隊列上面。

Exchange将RoutingKey和某Topic進行模糊比對,其中“”用來比對一個詞,“#”用于比對一個或者多個詞。例如“com.#”能比對到“com.rabbitmq.oa”和“com.rabbitmq”;而"login."隻能比對到“com.rabbitmq”。

RabbitMQ(一):RabbitMQ快速入門

Fanout Exchange

該類型不處理路由鍵,會把所有發送到交換器的消息路由到所有綁定的隊列中。優點是轉發消息最快,性能最好。

RabbitMQ(一):RabbitMQ快速入門

Headers Exchange

該類型的交換器不依賴路由規則來路由消息,而是根據消息内容中的headers屬性進行比對。headers類型交換器性能差,在實際中并不常用。

在雲計算和容器技術大熱的今天,不會Docker顯得未免太out了吧。Docker提供一種安全、可重複的環境中自動部署軟體的方式,本文使用Docker進行安裝RabbitMQ。

進入官方下載下傳位址,選擇使用Docker安裝,跳轉到dockerhub檢視鏡像。

RabbitMQ(一):RabbitMQ快速入門

我選擇3.8.0-beta.4-management進行安裝,帶有management是含有管理界面的。

拉取鏡像和啟動:<code>docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.8.0-beta.4-management</code>

檢視鏡像:

打開浏覽器通路localhost:15672,如果你和我一樣裝在虛拟機上面的話,需要打開虛拟機ip:15672

RabbitMQ(一):RabbitMQ快速入門

進行填寫賬号密碼:預設賬号密碼都是guest.

RabbitMQ(一):RabbitMQ快速入門

到此,RabbitMQ已經安裝并運作起來了。

本文介紹了RabbitMQ是什麼、RabbitMQ核心概念、常用交換器類型、用Docker安裝RabbitMQ等内容,看完本文,想必對于RabbitMQ已經有了一些初步的了解了,後面的世界更精彩。

本文參考慕課網免費課程:《RabbitMQ消息中間件極速入門與實戰》。

由于部落客也是在攀登的路上,文中可能存在不當之處,歡迎各位多指教! 如果文章對您有用,那麼請點個”推薦“,以資鼓勵!