RabbitMQ消息模型概覽(簡明教程)

来源:https://www.cnblogs.com/iyangyuan/archive/2018/09/02/9575683.html
-Advertisement-
Play Games

小菜最近用到RabbitMQ,由於之前瞭解過其他消息中間件,算是有些基礎,所以隨手從網上搜了幾篇文章,準備大概瞭解下RabbitMQ的消息模型,沒想到網上文章千篇一律,寫一大堆內容,就是說不明白到底怎麼回事,真是逼小菜寫博客… 首先說明本文只適合有消息中間件基礎的讀者,本文不會講解基礎概念,而是一針 ...


     小菜最近用到RabbitMQ,由於之前瞭解過其他消息中間件,算是有些基礎,所以隨手從網上搜了幾篇文章,準備大概瞭解下RabbitMQ的消息模型,沒想到網上文章千篇一律,寫一大堆內容,就是說不明白到底怎麼回事,真是逼小菜寫博客…

     首先說明本文只適合有消息中間件基礎的讀者,本文不會講解基礎概念,而是一針見血的指明RabbitMQ該怎麼用,告訴讀者RabbitMQ能做什麼,而不是像網路上其他文章那樣花里胡哨抓不住重點。

     好了,直入正題。

 

simple簡單隊列

 

     這種隊列,純屬RabbitMQ搞的一個花樣,僅僅是個概念而已!並不是實際的隊列類型!他就是在假設某個隊列只有一個消費者,也就是說,讀者在實際使用中,某個隊列傻傻的只用一個消費者去消費,這就叫simple簡單隊列啦,應用場景極少,一般情況下消費端都會有多個消費者。

 

Fair dispatch公平分發

 

     這種隊列讓人一看,有點蒙逼,實際上這個概念非常非常簡單,如果讀者用過redis的話,這個隊列模式很像redis的list用法,只不過redis是拉取模型,而mq是推送模型。

     這個公平,可不是說消息平均的發送給消費者,恰恰相反,消費者消費消息的多少,完全取決於消費者的處理能力,能者多勞,相當於消費者主動從mq中取消息,而不是被mq安排消息。

     實現上也不難理解,消費端消費數據時,會有一個確認消費完成的動作,mq收到消費完成的通知後,才會繼續向該消費者發送消息,因此,如果消費者處理速度快,那麼最終mq向它發送的消息就多,如果消費者處理的慢,mq向它發送的消息就少。

     在這小菜貼出java代碼實現的關鍵點:

RabbitMQ Fair dispatch公平分發

     當然,這是消費端代碼,僅僅在消費端做處理即可,對於生產端來說是透明的,不需要做任何處理。

 

Round-robin輪詢分發

 

     所謂輪詢分發,就是公平分發的退化版,打開自動通知,去掉手動通知,去掉消費端消費條數限制,就是輪詢分發啦!!!

     其實輪詢分發就是利用了自動通知參數,開啟了自動通知,mq根據一個簡單的規則(比如取模運算),先確定好哪些消息發送給哪些消費者,無論消費者處理能力如何,這些消息都得讓你處理,因此每個消費者最終處理的消息數量,是相同的(忽略"消息數量/消費者"不能整除的情況)。

     這種模式很明顯是有問題的,首先,這種模式不能很好的利用消費端的性能差異,做不到真正意義上的負載均衡,浪費資源;其次(只是猜測),這種模型還有可能造成大量消息堆積在消費者容器中,這是非常危險的,不僅會造成消息丟失,還有可能壓垮消費者。

 

publish_subscribe發佈訂閱模式

 

     RabbitMQ 中有一個交換機Exchanges的概念,發佈訂閱就是通過交換機實現的。

     交換機的概念非常簡單,就是一個轉發器,有了交換機之後,生產端先把消息發送到交換機,然後交換機再把消息發送到與其綁定的消息隊列,這樣就解決了生成端如何把一條消息批量發送到多個消息隊列的問題。

     交換機本身沒有數據存儲能力,僅僅是一個代理,可以理解成nginx。

     因此,實現發佈訂閱的關鍵在於:

 

          ·  生產端(發佈端)直接發送消息到交換機,而不是具體的消息隊列。

          ·  多個消費端(訂閱端)將自己的消息隊列綁定到同一個交換機上。

 

     這樣就實現了發佈訂閱。

 

routing路由模式

 

     路由模式僅僅基於發佈訂閱搞了一點小事情,在發佈訂閱模式中,交換機無腦向所有與之綁定的消息隊列發送消息,而路由模式對交換機做了一些限制,它指定了一個route key,生產端向交換機發送消息時,指定消息的route key,消費端將消息隊列綁定到交換機時,也指定該隊列消費的route key,這樣一來,交換機就可以根據消息的route key,將該消息轉發到綁定(消費)該route key的消息隊列。

     生產端關鍵點:

RabbitMQ routing路由模式生產者 

     消費端關鍵點:

 RabbitMQ routing路由模式消費者

 

topic主題模式

 

     RabbitMQ又開始搞花樣了,咋一看topic小菜還以為是kafka里的topic概念呢,弄的莫名其妙。

     主題模式其實就是路由模式的一個加強,而且是非常非常非常簡單的一個加強:route key支持通配符。

     主題模式和路由模式完全一樣,只不過是消費端route key不用寫死,增加了一個模糊匹配的功能,這樣在某些場景下,消費端就不用逐一綁定所有監聽的route key,直接用抽象的通配符表示即可,當然,這是針對消費端的優化,與生產端無關。

 

關於RabbitMQ的可靠性

 

     消費端的消費可靠性,已經在"Fair dispatch公平分發"章節中做了介紹,即利用手動通知告訴mq消費成功,但通知也有不可達的可能,進而涉及到重發,具體的處理細節,讀者自行查閱資料。

     生產端的提交可靠性,可以通過mq的回調機制實現,即生產端發送消息時自己維護一份已發送消息的集合,mq收到某條消息之後,會向生產端發送一個接收成功確認(體現在代碼中就是回調),然後生產端根據確認消息的唯一id,從自己維護的已發送消息集合中移除該消息,從而確保每條消息都成功發送到了mq。

     假如某些消息未成功到達mq,那麼就不會有對應消息的確認,最終集合中會有剩餘元素(理想情況下是沒有的),這些剩餘元素,就是發送失敗的消息,需要重發。

     簡單展示下代碼關鍵點( 生產端):

 RabbitMQ消息可靠性

 

     雖然確認機制可以保證消息的可靠性,但是必然帶來性能損失,因此到底需不需要開啟生產端或消費端的確認機制,需要根據業務場景具體分析。

 

一些註意事項

 

     RabbitMQ的Connection是昂貴的,但Channel是廉價的,在多線程環境下,儘量創建少數Connection,然後在每個Connection中創建多個Channel,利用Channel實現Connection復用,從而提高系統性能。很像Java NIO里的Selector到Channel的多路復用。

     生產端發送消息時,同一個Channel的basicPublish方法並不是線程安全的,因此更加體現出多Channel的重要性。如果生產端需要使用多線程發送消息,那麼必須創建多個Channel,每一個線程單獨使用一個Channel,但是這些Channel可以來自同一個Connection。假如線程數量過多,那麼也不可以無限制的創建Channel,需要使用Channel Pool(連接池)的思路去控制併發。

     對於同一個Channel而言,發送消息和接受消息是互不影響的,可以進行併發操作。

 

吐槽

 

     最後吐槽一下RabbitMQ客戶端API設計的真難用,同一個API竟然通過參數值重載,就比如向消息隊列發送消息是這樣:

 

 channel.basicPublish("","隊列名稱", null, message.getBytes()); 

 

     然後向交換機發消息是這樣:

 

 channel.basicPublish("交換機名稱","route key", null, message.getBytes()); 

 

     同一個方法,第二個參數的含義,竟然是通過第一個參數是否為空決定的,厲害了~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 進程調用 exit() 退出執行後,被設置為僵死狀態,這時父進程可以通過 wait4() 系統調用查詢子進程是否終結,之後再進行最後的操作,徹底刪除進程所占用的記憶體資源。 wait4() 系統調用由 linux 內核實現,linux 系統通常提供了 wait()、waitpid()、wait3()、 ...
  • linux或者OS X系統中,使用“dd”命令可以直接在終端命令行模式下,製作ISO鏡像的系統安裝盤. 一、linux系統以centOS7為例. 鏡像路徑: ISO格式的鏡像文件存放位置 USB路徑: /dev/sdb 這裡要註意的是: (1)USB設備不能已經掛載到其它目錄,否則會提示出錯.如果系 ...
  • MAC中ROOT用戶很少用到,有時又手賤,給設了密碼,過一陣忘了密碼,很尷尬😅 分享個小技巧: 在MAC開機讀條之前按住“ command + S ”,會進入字元界面,按照提示,依次輸入下麵3條命令: 1. /sbin/fsck -fy #回車後等待出現“#”提示符 2. /sbin/mount ...
  • 一、測試環境 OS version: CentOS Linux release 7.5.1804 (Core) docker cluster : master 1 + data node 4 docker version: 1.13.1 二、材料準備 1. dockerfile 文件,如下 /opt ...
  • 前言 在開始之前,請在心中默念三遍: Arch Linux 是世界上最好的發行版, 我一定能掌握她. 環境 VM ware + UEFI + 500G 虛擬磁碟 + 2G 記憶體 + 橋接網路 下載鏡像 進入這裡挑個最新的就好, https://mirrors.tuna.tsinghua.edu.cn ...
  • hbase 單機安裝部署及phoneix 單機安裝 Hbase 下載 (需先配置jdk) 解壓安裝 修改配置文件 配置文件修改 啟動 hbase 修改環境變數 環境變數配置 安裝測試 安裝phoneix 下載 解壓到目錄 將 修改 hosts文件(必須配置) 重啟habse 啟動phoneix 可能 ...
  • 最近公司新配置的win10電腦,由於測試關於windows系統上項目的安裝程式時預設使用了c盤安裝,發現安裝後的項目不是崩潰就是運行沒結果的,偶然間發現同一個安裝程式在d盤或其他非系統盤安裝則正常。很自然會懷疑這是安裝之後的項目在c盤沒有足夠的讀寫許可權的原因。果然在網上查找相關原因後發現是因為win ...
  • 這隻是我自己的隨筆博客~,用於偶爾回憶知識,可能存在一些錯誤,如有錯誤,歡迎指正~ 首先對於JDBC連接MySQL,要瞭解基本的框架結構 畫的比較爛,大約就是這樣的結構 然後看一下具體實現的 代碼:; 上面這個是通過單例模式 建立了DBUtil這樣一個類。通過這個類可以乾什麼呢?可以實現 資料庫的連 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...