上回介紹了 message queue 的基本觀念與使用時機(想複習觀念的可以看上一篇),今天則要介紹業界常用的第三方 message queue 服務 — RabbitMQ,其他業界常用的第三方 service 則有 Kafka、AWS SQS…等,雖然各個服務實作方式與內建功能會有些許不同,但底層的概念基本上與上一篇文章介紹的內容大同小異。
(以下圖片來源出自 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 多了 exchange 這個元件,不過不用擔心,現在來一個一個介紹 RabbitMQ 中的元件屬性吧!
Producer:
負責丟訊息到 Queue 中,若有定義 Exchange,則丟給 Exchange 決定要給誰。
Consumer:
負責接收來自 Queue 的訊息。
Queue:
負責存放所需要的資料,跟資料結構的 Queue 一樣,有先進先出 (FIFO) 特性,每個 Queue 都會有他的名字當 id。
Exchange:
用來決定 Producer 給的資料要丟給哪一個Queue,主要有這四種方式:
那麼透過以上 Exchange 的幾種方式,可以做到什麼事呢?
RabbitMQ 官網上的圖示解釋的滿清楚的,廢話不多說直接上圖!
不透過 Exchange 直接送到指定的 Queue
透過 Exchange 的 fanout 特性,達到訂閱 Queue 的 Consumer 都可以收到訊息。
透過 Exchange 的 direct 特性,達到類似 routing 的功能,將訊息 filter 到特定的 Queue。
透過 Exchange 的 topic 特性,每個 Queue 都有屬於自己的分類。
如果需要回傳訊息的話則需要透過 RPC。
剛剛介紹了 RabbitMQ 中的元件,而其實每個元件都有很多對應的屬性的,這邊直接放圖讓大家參考參考
Q: 如何實作可靠的訊息佇列?
A: 錯誤處理 (Error handling) 。
Q: How ?
自動 Retry -> Retry 一定次數仍然不行 -> 人為處理
錯誤處理的流程可以有百百種,不如試著畫出自己的錯誤處理流程吧!
今天簡單介紹了 RabbitMQ 的元件以及其屬性,也帶過了透過 RabbitMQ Exchange 的不同特性可以達成的功能,最後也淺淺的講到錯誤處理機制。不過很多第一次碰 RabbitMQ 或是 Message Queue 的人應該會有聽沒有懂吧,或是就算理解了原理也不知道如何實際在程式中運用,這邊得告訴大家
RabbitMQ 官方元件範例十分完整!
RabbitMQ 官方元件範例十分完整!
RabbitMQ 官方元件範例十分完整!
很重要所以說了三遍,有興趣的讀者可以自行去研究看看。
在下一篇文章中會用 Restful API 簡單搭配 RabbitMQ,嘗試看看現實中可能的 use case(當然是簡化版啦)。
想盡辦法當好一個Junior Backend Developer
用舒服的姿勢開發 Python Project
https://godleon.github.io/blog/ChatOps/message-queue-concepts/