RabbitMQ 基礎介紹 - 名詞解釋及 Exchange Type

什麼是 RabbitMQ ?

RabbitMQ 是一個 message broker,用來實現服務解耦。解耦聽起來很抽象,簡單來說,就是透過拆解程式碼的運作,避免服務的耦合性過高。

使用情境

舉例情境:目前運行中的專案為購物網站,想新增一個功能,當客戶訂單成立後發 email 到客戶信箱做確認留底。

從上述的情境中,運作流程會類似這樣

從流程看來,購物網站的商業邏輯和發送通知的程式碼會是綁在一起的,然而發送通知實際上能夠抽離出來,獨立作為一項服務,專門發送通知的服務。

此時服務解耦後會像這樣

購物網站透過 RabbitMQ 傳遞訊息,告訴通知服務該發信給客戶囉,客戶剛結完帳了。然而這樣做的好處是什麼?

為何需要 RabbitMQ?

服務解耦(service decoupled)的用意在於避免原本的專案因為參雜過多的功能,使得一小部份的 bug 就讓整個服務中斷。

以上方的情境來說,如果發送通知是包含在購物網站中,此時這部份的程式碼出了問題,整個專案受到影響,無法結帳,公司業務會停擺,但如果發送通知是抽離出來,獨立作為一項服務的話,此時即便通知的程式碼出問題,公司業務能夠持續運作。

概念圖

名詞解釋

要了解 RabbitMQ,認識專有名詞和定義有很大的幫助,以下為使用 Message Queue 時的常見名詞,可以搭配概念圖一起看。

名稱 解釋
message RabbitMQ 裡所傳遞的物件
queue message 所放置的地方
producer 生成 message 並傳入 queue 裡的角色
consumer 從 queue 中提取 message,並執行內容的角色
exchange 決定 message 要傳入哪個 queue
routing key 在 message 身上挾帶的資訊,類似地址,告訴 exchange 這個 message 要被傳入哪個 queue 中
binding 表示 exchange 和 queue 之間的關係
channel 一個 connection 中能包含多個 channel,可以把 channel 想成虛擬的 connection 或 子 connection
connection 連結 app 和 RabbitMQ,這邊介紹的是 AMQP 0-9-1 ptotocol
vhost 想成一個 container,vhost 裡頭底下包含了 exchange 和 queue

AMQP 0-9-1 Model 介紹

AMQP (Advanced Message Queuing Protocol),用於 Broker 和其他機器之間的傳輸協議,從上方的概念圖看到,RabbitMQ 扮演著 broker 的角色,介於 Producer 和 Consumer 之間,而 Producer, Broker, Consumer 分別是三台不同的機器,AMQP 就是用於扮演他們之間溝通的協議。

Exchange 類型介紹 (Direct, Fanout, Topic)

在 RabbitMQ 中,Message 從 Producer 傳到了 Exchange 後,如何分配給 Queue,取決於 Exchange 的類型和 binding,這邊介紹三種 Exchage 類型

序號 名稱
1 Direct
2 Fanout
3 Topic

Direct

Direct 為預設的 Exchange 類型,如同名字所寫,Direct Exchange 就直接透過 message 上的 routing_key 以及 binding 的 routing_key 找到對應的 Queue,概念如下圖,圖中的 message 會被送到 Queue 3 中。

Fanout

Fanout 個概念類似廣播,廣播一發送,只要在收聽該電台的人都聽得到,Fanout 在設計上忽略 routing_key,只要 Exchange 收到 message,會將同樣的 message 發送給所有 binding 的 Queues.

Topic

Topic 相對上面兩種類型稍微複雜一些,Exchange 會發送 Message 給多個 Queue,舉例來說,當客戶退貨的時候,可能需要做發送通知信以及商品數量增加兩件事,而這兩件事可能分送給不同的 Queue 去做處理。

在 Topic Exchange 中, message 的 routing_key 是有特定規範的,會是一段文字,中間由 . 區隔,例如 product.phone.new,不限制使用多少字,只要小於 255 bytes。

rounting_key 中會出現 #*,用於表達一個 pattern。# 代表沒有任何或是多個單字,* 代表一個單字。(當 rounting_key 中沒有使用到 * 或是 #,其實跟 Direct Exchange 會是一樣的。)

舉例

routing_key qualified
*.*.apple shop.food.apple, order.item.apple
trade.# trade, trade.car, trade.car.cancelled

以下方的示意圖來看,message 所夾帶的 routing_keytrade.phone.cancelled,從各個 binding 的 routing_key 確認後,會傳送到 Queue 1Queue 3

後記

接觸到 Message Queue 才發現裡面的學問很大,RabbitMQ 可以應用在很多場景,這篇有基礎的概念介紹和名詞解釋,之後要再花時間鑽研鑽研實際應用的部份。

參考資料

https://www.rabbitmq.com/getstarted.html

https://www.cloudamqp.com/blog/part1-rabbitmq-for-beginners-what-is-rabbitmq.html

https://www.rabbitmq.com/tutorials/amqp-concepts.html

https://blog.csdn.net/hao134838/article/details/71710067

Tags:
# python
# rabbitmq
# queue