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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...