新手必看:RabbitMQ超詳細解析,圖解六大模式應用場景

更新於 2024/06/27閱讀時間約 18 分鐘

最近剛好在對RabbitMQ進行研究,發現網路上對RabbitMQ的文章都不太夠全面,這篇文章來幫大家統整一下關於RabbitMQ的六種常見模式及應用,另外也會非常詳細的介紹各個參數代表的意義,對RabbitMQ有興趣的話,就歡迎看下去吧~

raw-image

Message Queue是什麼?

RabbitMQ其實是一種Message Queue(後面會簡稱會Queue),所以我們先來了解什麼是Queue吧!Queue提供了一個強大且靈活的平台,主要用於應用程式之間傳遞訊息。

Queue主要由三個元件所組成,

  1. Producer(生產者):主要用來發送訊息,訊息會透過Broker傳到Consumer
  2. Consumer(消費者):主要用來接收訊息,會從Broker去接收Producer傳來的訊息
  3. Broker(佇列):在Producer和Consumer之間扮演橋樑的角色,負責轉送訊息
RabbitMQ基本架構

RabbitMQ基本架構

接下來介紹Queue的兩個最常見的用途,分別是任務緩衝系統解耦

任務緩衝

譬如碰到有任務必須運算很久(CPU Bound的任務),像用AI生成一張圖片要很長的時間,如果短時期碰到很多人想同時下載圖片,伺服器就有可能爆掉,也有些封包可能會遺失。Queue可以扮演了一個任務緩衝的角色,讓任務進行「排隊」,使得每個任務都不會遺失,排隊的使用者也可以先去做其他事(非同步任務)。

系統解耦

除此之外,Queue也可以幫助任兩個系統進行解耦,Producer和Consumer並不需要記得彼此的位址,只需要記得Queue在哪裡即可,如此三者可以架設在不同主機,也不需要使用相同語言開發,最重要是可以很方便依據需求對伺服器進行水平擴展(增加Server數量)

舉例來說,原本Cient端要傳訊息交給Server端解決,但用戶數量突然增加,伺服器來不及處理完所有任務,由於Client端是向Queue傳遞訊息.可用增加Server數量取代增加Server效能,成本下降非常多,也大幅提高可擴充性

RabbitMQ有什麼特色?

RabbitMQ是一個實現了AMQP協議的開源的Message Queue,比一般傳統的Queue多了一個Exchange,方便更彈性的應用,而RabbitMQ的特色有以下的幾點:

  1. 提供了靈活的路由機制,利用Exchange將訊息進行多種方式的轉送
  2. 提供高可用性、高數據可靠性的功能,利用分散式部署的方式保障數據的安全
  3. 提供數據持久化的功能,保障RabbitMQ進行重啟的時候數據仍可以保存
  4. 提供多種語言的API可供調用,包括Go, Java, PHP, C#, Python, JavaScript…
  5. 提供清楚的可視化工具,方便使用UI進行管理

RabbitMQ的六種應用模式

RabbitMQ總共提供六種常見的使用模式,方便使用者對應不同的情境進行客製化的使用,從最基礎的Simple、Worker模式,到有使用的Exchange的Pub/Sub、Headers、Routing、Topic模式。

Simple模式

Simple模式是最基本的模式,由Producer、Worker、Broker各一個所組成,因為只有一對一,所以主要處理最一般的非同步任務。

Simple模式,來源:RabbitMQ

Simple模式,來源:RabbitMQ

Worker模式

Worker模式則是進階的Simple模式,當今天Producer的任務傳的太多,就可以發揮RabbitMQ藉由系統解耦,能快速水平擴展的優勢,藉由增加Consumer的數量,加快處理訊息的速度。

範例說明:

訊息若沒經過特別處理,則會依照如下圖的Round-Robin的模式,將A,B,C的三則訊息輪流交給Consumer 1, Consumer 2進行處理,是工廠為了要接大量的訂單,而不斷增加產線加快速度的模式。

常見應用:

1.高流量的任務處理,像是多個需要套用AI模型的任務

Worker模式,來源:RabbitMQ

Worker模式,來源:RabbitMQ


前面兩個模式主要探討Queue和Consumer的關係,接下來的模式都是使用Exchange這個元件,但Exchange的類型不同,而產生不同模式,可以將訊息依據不同規則,只轉送到符合規則的Queue,著重於Exchange和Queue的關係,那我們就開始吧!


Publisher/Subscriber模式

首先是Pub/Sub模式,又稱發布者/訂閱者模式,Exchange的類型是fanout,也就是將訊息全部轉送,當Exchange從Producer收到訊息,只將訊息轉送給和Exchange綁定的Queue,每個和Exchange綁定的Queue都會拿到同一份訊息。

範例說明

以下圖為例,Exchange收到A,B,C三則訊息,由於Q1, Q2都給Exchange綁定,所以兩個Queue都會同時收到A,B,C三則訊息,再交由Queue後面的Consumer進行處理,所以有Exchange的模式,都是可以跟前面Simple、Worker模式進行組合搭配。

常見應用

  1. Youtube訂閱制,當YT有影片更新時,每個訂閱者都可以收到相同的訊息通知
  2. 當廣告的電子報發布時,所有訂閱者都可以收到相同的電子報
Pub/Sub模式,來源:RabbitMQ

Pub/Sub模式,來源:RabbitMQ

Routing模式

接下來是Routing模式,Exchange的類型是direct,當你希望將Producer送出的訊息加上特定Key,只傳送給有匹配Key的Queue時,就可使用這種模式。

Routing的特色是一對一精確比對,每則訊息最多只有一個Routing Key,每個Queue都可以跟Exchange用多組Key進行綁定,訊息只會轉送給兩個Key完全相同的Queue。

Queue和Exchange綁定的所有Key.contains(訊息的Routing Key),才會進行轉送

範例說明

如下圖Q1就和Exchange綁定一個Key(error),Q2則跟Exchange綁定多組Key(info, warn, error),當有則帶Key的訊息從左邊Producer(P)傳到Exchange,Exchange就會將訊息做不同的轉送。

1.Key為error:訊息複製兩份,分別傳送給Q1和Q2,兩個都和Exchange有用error綁定2.Key為warn或info:直接將訊息傳給Q2,只有Q2有用warn和info進行綁定
3.Key不為以上三者:訊息會直接被丟棄,Exchange找不到有匹配的Queue。或是也可以建立一個Dead Letter Exchange,將被丟棄的訊息做額外處理

常見應用

1.進階Youtube訂閱制,每個訂閱者可根據不同會員等級收到不同通知
2.Log系統應用,Q1可以專門儲存error log,Q2每個log都接收傳到Console

 Routing模式,來源:RabbitMQ

Routing模式,來源:RabbitMQ

Topic模式

接下來是Topic模式,Exchange的類型是topic,當你希望將Producer送出的訊息加上特定Key,只傳送給有相似Key的Queue時,就可使用這種模式。

Routing的特色是一對一模糊比對,每則訊息最多只有一個Routing Key,每個Queue都可以跟Exchange用多組Key進行綁定,訊息只會轉送給兩個Key相似的Queue。

和前面Routing模式的最大差異是:

綁定的Routing Key增加*(star)和#(bash)兩個可模糊比對的符號,(*)代表一個單詞,(#)代表0到多個單詞,但符號間必須用(.)進行隔開,如(*.orange.*),則代表orange的前後必須也只能有一個單詞,如lazy.orange.rabbit則符合規則。
若未使用這兩個符號,則跟Routing模式完全相同

範例說明

如下圖Q1就和Exchange綁定一個Key(*.orange.*),Q2則跟Exchange綁定兩個Key(*.*.rabbit、lazy.#),當有則帶Key的訊息從左邊Producer(P)傳到Exchange,Exchange就會將訊息做不同的轉送。

1.Key為lazy.orange.elephant:訊息複製兩份,分別傳送給Q1和Q2,因為符合

Q1的規則:orange前面(lazy)、後面(elephant)各有一個單詞
Q2的規則1:完全沒有Rabbit所以不符合
Q2的規則2:lazy後面有多個單詞(orange, elephant)

2.Key為happy.lazy.orange:訊息直接被丟棄,因沒有完全符合Q1、Q2的任一個規則

Q1的規則:不符orange前面只能有一個單詞(happy和lazy)、不符後面必須一個(0個)
Q2的規則1:完全沒有Rabbit所以不符合
Q2的規則2:符合lazy後面有0到多個單詞(他0個)、但不符lazy前面沒有單詞(happy)

Go範例實作

# producer.go
conn, err := amqp.Dial(util.RabbitMQ_host)
if err != nil {
log.Printf("Error occurs when connect to RabbitMQ: %v", err)
return
}
defer conn.Close()

# 建立channel連線
ch, err := conn.Channel()
if err != nil {
log.Printf("Error occurs when set Channel: %v", err)
return
}
defer ch.Close()
err = ch.PublishWithContext(ctx,
"Exchange_Name" , // Exchange名稱
"", // Routing Key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "application/json",
Body: []byte(body)
})


# consumer.go 
# 建立
args := amqp.Table{}
q, err := ch.QueueDeclare(
"Queue_Name", // Queue_Name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
args, // arguments
)
if err != nil {
fmt.Printf("Error occurs when set Queue: %v", err)
return
}

# 設定Binding的規則
err = ch.QueueBind(
q.Name, // Queue名稱
"Routing_Key"  , // Routing Key
"Exchnage_Name", // Exchange名稱
false, // 不等待狀態
nil, // 額外參數
)
if err != nil {
log.Printf("Error occurs when set Queue: %v", err)
return
}

# 建立Consumer
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)

常見應用
1.log有多個層級時,像是error.serious.log和error.light.log只要綁定error.#一個Key,就可以同時接收到多種log的Queue,不需要同時綁定兩個Key,簡潔性會更高。

Topic模式,來源:RabbitMQ

Topic模式,來源:RabbitMQ


Header模式

接下來介紹是Header模型,Exchange Type設定為headers,這個模式網路上比較少人有介紹,因為也比較複雜一些,想要一次比對多個值時可以使用這種模式。

Header的特色是整組全對整組對一個,由於必須在規則上綁定多個鍵值,不能使用前面的Key而需要改使用headers,以Go語言為例。

1.Producer的的部分必須把用來比對的多個鍵值放到amqp.Publishing的headers

2.Consumer必須先建立一個amqp.Table,將想比對的所有值放進去後,再把Table放在QueueBind裡的arguments,除此之外Table必須放入一個x-match的key,他的value可以是any或是all,分別代表整組對一個整組全對的規則

  • {"x-match": "all"}: 代表Table裡的headers和訊息的headers必須完全相符
  • {"x-match": "any"}: 代表Table裡的headers和訊息的headers有一個相符即可

符合規則的訊息,就會從Exchange被轉送到所有有綁定、規則也符合的Queue裡面,即可完成整串流程。

範例說明

為了避免大家搞混,這邊同時把Routing, Topic, Headers三種模式用一張圖進行比對,Header模式為最下面的流程表。

1.Queue的規則1:x-match是any,訊息只要有{color:red}的header會被轉送

2.Queue的規則2:x-match是all,必須同時有{color:red},{legs:4}兩個才會轉送

所以左邊第一則訊息符合規則1,會被轉送到Queue,左邊第二則訊息同時符合規則1和2也會被轉送,但不管符合幾個規則,都只會被轉送一次而已。

RabbitMQ模式

RabbitMQ模式

Go範例實作

# producer.go
contentType := "application/json"
err := ch.PublishWithContext(ctx,
"Exchange_Name" , // Exchange名稱
"", // Routing Key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: contentType,
Body: []byte(body),
Headers: amqp.Table{"ContentType": contentType,
"key1": "value1"},
})


# consumer.go 
headers := amqp.Table{
"x-match": "any",
"Content-Type": "application/json",
"key1": "value1"
}
err := ch.QueueBind(
"Queue_Name", // Queue名稱
"", // Routing Key
"Exchange_Name" , // Exchange名稱
false, // 不等待狀態
headers,
)

常見應用

譬如說需要既有Key的比對,又希望額外增加Content-Type必須為application/json的比對條件,就可以把兩個值同時放入amqp.Table,但請注意headers和實際上封包的headers完全沒有關係,比對時只會比對amqp.Table內的鍵值,所以建議使用上面同時使用contentType變數的做法,才可以達到效果喔。

總結

RabbitMQ目前最適合的使用場景是在對Queue不太熟悉且需求也不太複雜,RabbitMQ可以非常快速讓你快速搭建起Queue的基本架構以及多種路由規則,但若遇到量能較大的需求,如每秒數百萬訊息的需求,建議可以參考Kafka或其他Queue的元件喔~

以上就是RabbitMQ的基礎介紹,希望能幫從0開始的新手們了解RabbitMQ,希望對你有幫助。之後反應不錯的話,我會再撰寫關於更多進階參數使用,如Priority Queue及Go範例文章,若有錯誤或不周延的地方,再請各位大神指教、糾正了~


你可能還會想看:

CNN實作Kaggle貓狗影像辨識(Pytorch)

幫非結構化資料找個家,快速入門MinIO(一):基本概念介紹

AWS CCP考試準備資源與心得分享(Certified Cloud Practitioner)



avatar-img
1會員
37內容數
大學科系選擇技巧、高中升學考試經驗分享
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
吉米富的沙龍 的其他內容
這半年因為準備工作開始摸AWS,用Free-Tier摸了大概3個月左右後,雖然會用一些簡單服務部署Side Project,但AWS真的太博大精深,覺得還是對AWS的框架有個了解比較好,有證照對於履歷上還是比較有幫助,這篇會簡單介紹一下AWS的證照類型,著重在考試準備資源、方式和考試當天的過程,有興
之前實習時剛好公司有需要實作MinIO相關自動化腳本的需求,算是把MinIO摸得蠻仔細的,剛好網路上沒有太多相關中文資訊,趁這個機會來介紹一下MinIO,若有興趣就歡迎看下去吧~ MinIO是什麼? MinIO是一個使用Golang開發的雲端儲存的開源專案,專注於儲存大量的非結構化的數據,如圖片、影
最近剛好修了Pytorch相關的課,在Kaggle上也丟了個比賽,想說就來分享一下Pytorch的入門實戰,我會實作一個最入門的用CNN辨識貓狗的程式,但關於CNN理論的部分我不會提到太多,有興趣就麻煩再去搜尋了~ CNN是什麼? 先簡單介紹一下CNN,CNN的全名是(Convolutional N
這半年因為準備工作開始摸AWS,用Free-Tier摸了大概3個月左右後,雖然會用一些簡單服務部署Side Project,但AWS真的太博大精深,覺得還是對AWS的框架有個了解比較好,有證照對於履歷上還是比較有幫助,這篇會簡單介紹一下AWS的證照類型,著重在考試準備資源、方式和考試當天的過程,有興
之前實習時剛好公司有需要實作MinIO相關自動化腳本的需求,算是把MinIO摸得蠻仔細的,剛好網路上沒有太多相關中文資訊,趁這個機會來介紹一下MinIO,若有興趣就歡迎看下去吧~ MinIO是什麼? MinIO是一個使用Golang開發的雲端儲存的開源專案,專注於儲存大量的非結構化的數據,如圖片、影
最近剛好修了Pytorch相關的課,在Kaggle上也丟了個比賽,想說就來分享一下Pytorch的入門實戰,我會實作一個最入門的用CNN辨識貓狗的程式,但關於CNN理論的部分我不會提到太多,有興趣就麻煩再去搜尋了~ CNN是什麼? 先簡單介紹一下CNN,CNN的全名是(Convolutional N
你可能也想看
Google News 追蹤
Thumbnail
本文探討了複利效應的重要性,並藉由巴菲特的投資理念,說明如何選擇穩定產生正報酬的資產及長期持有的核心理念。透過定期定額的投資方式,不僅能減少情緒影響,還能持續參與全球股市的發展。此外,文中介紹了使用國泰 Cube App 的便利性及低手續費,幫助投資者簡化投資流程,達成長期穩定增長的財務目標。
Thumbnail
許多新手搞不清楚,以為委託了就會成交,其實並不是這樣的! 委託單是委託單,成交是成交,委託成功不等於成交!!! 曾經也是新手的我,對於股票操作介面也是一知半解 所以特別針對委託與成交來說明,讓股票新手都能順利上手!
烏龜是一種很好養的小動物。如果你對動物毛髮過敏,但又很想養一隻小寵物的話,那麽幼龜就是一個很好的選擇。它既不會嚎叫,也不會出現傷人,並且花費相對較低。 如果你有養龜的意向,但是作爲新手完全沒有經驗的話,那麽這篇文章可以幫助到你。我們將會介紹適合新手的烏龜品種,養它的禁忌、必備用品和注意事項,並對新
最近有蠻多朋友再問怎麼投資理財 我自己的觀念,一定是先理財,再投資 先理好自己的財務狀況,再根據自己的財務狀況來進行投資 回想當年我剛出社會,對於財商也是完全一頭霧水 都是靠著自己摸索,還有哥哥的提點 一步一步的建構出自己的理財觀念,再進化到投資 所以我就來分享一下,一個剛出社會的新鮮人 對於
Thumbnail
第一課:你認為行銷對你來說是什麼?你為什麼想學行銷,動機是什麼?如果今天換個角度思考,換成你來教別人行銷你會教什麼? 行銷對我而言是將一樣人事物銷售給他人,使得可以賺到錢名聲地位等等,就是行銷。像是將自我行銷,不只因為賺錢,而是夾雜在其中的名聲或是地位都比賺錢更來得重要許多。
Thumbnail
正在考慮投資金融商品你的,是否覺得標的茫茫,股票、各式各樣的期貨等不知該如何選擇呢?別擔心,本篇就將針對期貨交易做簡單介紹,包含什麼是期貨、期貨類別、期貨市場風險、期貨交易流程等,以及期貨交易需要注意什麼,是新手投資必看的一篇,首先就先從期貨的定義與期貨與股票差異來開始看起吧!
Thumbnail
:化妝品怎麼挑? :什麼要買什麼不用買? :一定要買專櫃的嗎?還是開架的就可以了? :什麼顏色適合我? :到底要買哪些產品啊啊啊啊啊? 如果你是化妝新手、想要學化妝、或是化完妝覺得還沒有素顏好看⋯ 從膚質辨認、產品挑選、化妝手法、用品選擇⋯通通一次說清楚!
Thumbnail
王國之淚作為一款開放世界,探索和開荒可以說是遊戲的核心玩法,有著極為廣大的世界,但指引卻很少,有些玩家可能會不知道下一步要做什麼,或是去哪裡,所以這部影片就要來分享,遊戲前期開荒的幾個技巧和知識分享,幫助大家在探索海拉魯大陸時,能有更好的遊戲體驗,並以最高的效率開圖,那
Thumbnail
這部影片要來介紹薩爾達傳說,王國之淚中,每個玩家都必須會的六個戰鬥操作技巧,在遊玩王國之淚時,散佈於大地圖上的魔物是新手們的一大噩夢,常常一不小心就會死在魔物的手中,所以這部影片就要來帶大家了解戰鬥操作的六個小技巧,包括了王國之淚的新系統,讓戰鬥發生了什麼改變,還有新能
Thumbnail
睽違三年,即將前往東京旅行的你們,是否已經迫不及待大口呼吸日本空氣了呢?記得規劃1-2天時間,放慢旅行步調,走訪東京近郊的度假勝地,漫無目的逛逛街、散散步、吃美食、買伴手禮,為旅途留下一張又一張特別美好的照片吧! 由Funliday根據網路人氣行程特別整理2023年東京近郊新手旅行攻略:
Thumbnail
大家好~這裡是玫玫物語 要來分享Fire Emblem Engage的新手開荒攻略,遊戲中有許多應該要早點知道的事,像是解鎖飾品店的第一件事,就是應該把全部女角換裝成泳裝,這麼重要的資訊能不知道嗎??除此之外我還整理了八個實用的新手攻略,幫助大家節省大量遊戲時間,以及快速提升前期戰力
Thumbnail
本文探討了複利效應的重要性,並藉由巴菲特的投資理念,說明如何選擇穩定產生正報酬的資產及長期持有的核心理念。透過定期定額的投資方式,不僅能減少情緒影響,還能持續參與全球股市的發展。此外,文中介紹了使用國泰 Cube App 的便利性及低手續費,幫助投資者簡化投資流程,達成長期穩定增長的財務目標。
Thumbnail
許多新手搞不清楚,以為委託了就會成交,其實並不是這樣的! 委託單是委託單,成交是成交,委託成功不等於成交!!! 曾經也是新手的我,對於股票操作介面也是一知半解 所以特別針對委託與成交來說明,讓股票新手都能順利上手!
烏龜是一種很好養的小動物。如果你對動物毛髮過敏,但又很想養一隻小寵物的話,那麽幼龜就是一個很好的選擇。它既不會嚎叫,也不會出現傷人,並且花費相對較低。 如果你有養龜的意向,但是作爲新手完全沒有經驗的話,那麽這篇文章可以幫助到你。我們將會介紹適合新手的烏龜品種,養它的禁忌、必備用品和注意事項,並對新
最近有蠻多朋友再問怎麼投資理財 我自己的觀念,一定是先理財,再投資 先理好自己的財務狀況,再根據自己的財務狀況來進行投資 回想當年我剛出社會,對於財商也是完全一頭霧水 都是靠著自己摸索,還有哥哥的提點 一步一步的建構出自己的理財觀念,再進化到投資 所以我就來分享一下,一個剛出社會的新鮮人 對於
Thumbnail
第一課:你認為行銷對你來說是什麼?你為什麼想學行銷,動機是什麼?如果今天換個角度思考,換成你來教別人行銷你會教什麼? 行銷對我而言是將一樣人事物銷售給他人,使得可以賺到錢名聲地位等等,就是行銷。像是將自我行銷,不只因為賺錢,而是夾雜在其中的名聲或是地位都比賺錢更來得重要許多。
Thumbnail
正在考慮投資金融商品你的,是否覺得標的茫茫,股票、各式各樣的期貨等不知該如何選擇呢?別擔心,本篇就將針對期貨交易做簡單介紹,包含什麼是期貨、期貨類別、期貨市場風險、期貨交易流程等,以及期貨交易需要注意什麼,是新手投資必看的一篇,首先就先從期貨的定義與期貨與股票差異來開始看起吧!
Thumbnail
:化妝品怎麼挑? :什麼要買什麼不用買? :一定要買專櫃的嗎?還是開架的就可以了? :什麼顏色適合我? :到底要買哪些產品啊啊啊啊啊? 如果你是化妝新手、想要學化妝、或是化完妝覺得還沒有素顏好看⋯ 從膚質辨認、產品挑選、化妝手法、用品選擇⋯通通一次說清楚!
Thumbnail
王國之淚作為一款開放世界,探索和開荒可以說是遊戲的核心玩法,有著極為廣大的世界,但指引卻很少,有些玩家可能會不知道下一步要做什麼,或是去哪裡,所以這部影片就要來分享,遊戲前期開荒的幾個技巧和知識分享,幫助大家在探索海拉魯大陸時,能有更好的遊戲體驗,並以最高的效率開圖,那
Thumbnail
這部影片要來介紹薩爾達傳說,王國之淚中,每個玩家都必須會的六個戰鬥操作技巧,在遊玩王國之淚時,散佈於大地圖上的魔物是新手們的一大噩夢,常常一不小心就會死在魔物的手中,所以這部影片就要來帶大家了解戰鬥操作的六個小技巧,包括了王國之淚的新系統,讓戰鬥發生了什麼改變,還有新能
Thumbnail
睽違三年,即將前往東京旅行的你們,是否已經迫不及待大口呼吸日本空氣了呢?記得規劃1-2天時間,放慢旅行步調,走訪東京近郊的度假勝地,漫無目的逛逛街、散散步、吃美食、買伴手禮,為旅途留下一張又一張特別美好的照片吧! 由Funliday根據網路人氣行程特別整理2023年東京近郊新手旅行攻略:
Thumbnail
大家好~這裡是玫玫物語 要來分享Fire Emblem Engage的新手開荒攻略,遊戲中有許多應該要早點知道的事,像是解鎖飾品店的第一件事,就是應該把全部女角換裝成泳裝,這麼重要的資訊能不知道嗎??除此之外我還整理了八個實用的新手攻略,幫助大家節省大量遊戲時間,以及快速提升前期戰力