[基礎觀念系列] 讓任務排隊吧:Message Queue — (2)

圖片來源

上回介紹了 message queue 的基本觀念與使用時機(想複習觀念的可以看上一篇),今天則要介紹業界常用的第三方 message queue 服務 — RabbitMQ,其他業界常用的第三方 service 則有 Kafka、AWS SQS…等,雖然各個服務實作方式與內建功能會有些許不同,但底層的概念基本上與上一篇文章介紹的內容大同小異。

(文章部分圖片來源為 RabbitMQ 官方網站)

Why RabbitMQ ?

經過上一篇的介紹後,你可能會心想:“要自己實作 message queue 並不是辦不到的事啊,我努力一點多花點時間也是辦得到的!自己實作 queue 或是用 db 當作 queue 好像都可行欸!”,如果你有這個想法,試著回答以下問題吧:

如何避免兩個 consumer 同時拿到同一個 message ?

如何處理 Error Handling ?

如何處理 message 的順序問題 ?

這些問題你有想過嗎?當然這些也可以硬幹解決啦,不過與其花時間自行處理這些問題,還要承擔忽略少數狀況的風險,不如使用功能完整,效能也經過優化的服務,RabbitMQ 就是其中一個。

RabbitMQ 是實現 AMQP (Advanced Message Queuing Protocol,進階訊息佇列協議) 中間件設計的一種。伺服器端用 Erlang 語言編寫,支援多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,亦支持 AJAX。用於在分布式系統中存儲轉發訊息,在易用性、擴展性、高可用性等方面表現不俗。

RabbitMQ 元件介紹

從上圖中可以發現架構圖跟上篇文章中介紹的大同小異,不過 RabbitMQ 多了 exchange 這個元件,不過不用擔心,現在來一個一個介紹 RabbitMQ 中的元件屬性吧!

Producer:

負責丟訊息到 Queue 中,若有定義 Exchange,則丟給 Exchange 決定要給誰。

Consumer:

負責接收來自 Queue 的訊息。

Queue:

負責存放所需要的資料,跟資料結構的 Queue 一樣,有先進先出 (FIFO) 特性,每個 Queue 都會有他的名字當 id。

Exchange:

用來決定 Producer 給的資料要丟給哪一個Queue,主要有這四種方式:

  • Direct: 直接丟給指定的 Queue。
  • Topic: 類似 regular expression,設定 binding 規則,丟給符合的 Queue。
  • Headers: 透過傳送資料的 header 來特別指定所要的 Queue。
  • Fanout: 一次丟給全部負責的 Queue。

那麼透過以上 Exchange 的幾種方式,可以做到什麼事呢?

RabbitMQ 官網上的圖示解釋的滿清楚的,廢話不多說直接上圖!

Task Queue

不透過 Exchange 直接送到指定的 Queue

Publish/Subscribe

透過 Exchange 的 fanout 特性,達到訂閱 Queue 的 Consumer 都可以收到訊息。

Routing

透過 Exchange 的 direct 特性,達到類似 routing 的功能,將訊息 filter 到特定的 Queue。

Topics

透過 Exchange 的 topic 特性,每個 Queue 都有屬於自己的分類。

RPC

如果需要回傳訊息的話則需要透過 RPC。

RabbitMQ 的元件 ”屬性”

剛剛介紹了 RabbitMQ 中的元件,而其實每個元件都有很多對應的屬性的,這邊直接放圖讓大家參考參考。

Message 屬性

Queue 屬性

Exchange 屬性

RabbitMQ 失敗重試處理

Q: 如何實作可靠的訊息佇列?

A: 錯誤處理 (Error handling) 。

Q: How ?

自動 Retry -> Retry 一定次數仍然不行 -> 人為處理

錯誤處理的流程可以有百百種,不如試著畫出自己的錯誤處理流程吧!

小結

今天簡單介紹了 RabbitMQ 的元件以及其屬性,也帶過了透過 RabbitMQ Exchange 的不同特性可以達成的功能,最後也淺淺的講到錯誤處理機制。不過很多第一次碰 RabbitMQ 或是 Message Queue 的人應該會有聽沒有懂吧,或是就算理解了原理也不知道如何實際在程式中運用,這邊得告訴大家

RabbitMQ 官方元件範例十分完整!

RabbitMQ 官方元件範例十分完整!

RabbitMQ 官方元件範例十分完整!

很重要所以說了三遍,有興趣的讀者可以自行去研究看看。

在下一篇文章中會用 Restful API 簡單搭配 RabbitMQ,嘗試看看現實中可能的 use case(當然是簡化版啦)。

--

--