[基礎觀念系列] 讓任務排隊吧: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(當然是簡化版啦)。