主頁 > 軟體設計 > 訊息中間件RabbitMQ

訊息中間件RabbitMQ

2023-01-31 08:02:43 軟體設計

目錄
  • 什么是RabbitMQ?
  • 為什么使用MQ?MQ的優點
  • 訊息中間件比對
    • RabbitMQ
    • RocketMQ
    • Kafka
    • 選型建議
  • MQ 有哪些常見問題?ranbbitMQ如何解決這些問題?
    • MQ 有哪些常見問題?
      • 訊息的順序問題
      • 訊息的重復問題
      • 訊息積壓
    • rabbitMQ如何解決這些問題?
      • rabbitMQ解決訊息的順序方案
      • rabbitMQ解決訊息的重復問題方案
      • rabbitMQ解決訊息積壓方案
      • RabbitMQ訊息的可靠傳輸?訊息丟失怎么辦?
        • 生產者的訊息確認機制
        • 消費者的訊息確認機制
        • 訊息佇列的持久化
      • RabbitMQ高可用

什么是RabbitMQ?

RabbitMQ是一款開源的,Erlang撰寫的,基于AMQP協議的訊息中間件

為什么使用MQ?MQ的優點

  • 異步處理 - 相比于傳統的串行、并行方式,提高了系統的吞吐量,

  • 應用解耦 - 系統間通過訊息通信,不用關心其他系統的處理,

  • 流量削鋒 - 可以通過訊息佇列長度控制請求量,可以緩解短時間內的高并發請求,

  • 訊息通訊 - 訊息佇列一般都內置了高效的通信機制,因此也可以用在純訊息通訊上,比如實作點對點訊息佇列,或者聊天室等,

  • 日志處理 - 解決大量日志傳輸,

訊息中間件比對

ActiveMQ、RabbitMQ、RocketMQ、Kafka有什么優缺點?

ActiveMQ RabbitMQ RocketMQ Kafka ZeroMQ
單機吞吐量 比RabbitMQ低 2.6w/s(訊息做持久化) 11.6w/s 17.3w/s 29w/s
開發語言 Java Erlang Java Scala/Java C
主要維護者 Apache Mozilla/Spring Alibaba Apache iMatix,創始人已去世
成熟度 成熟 成熟 開源版本不夠成熟 比較成熟 只有C、PHP等版本成熟
訂閱形式 點對點(p2p)、廣播(發布-訂閱) 提供了4種:direct, topic ,Headers和fanout,fanout就是廣播模式 基于topic/messageTag以及按照訊息型別、屬性進行正則匹配的發布訂閱模式 基于topic以及按照topic進行正則匹配的發布訂閱模式 點對點(p2p)
持久化 支持少量堆積 支持少量堆積 支持大量堆積 支持大量堆積 不支持
順序訊息 不支持 不支持 支持 支持 不支持
性能穩定性 一般 較差 很好
集群方式 支持簡單集群模式,比如'主-備',對高級集群模式支持不好, 支持簡單集群,'復制'模式,對高級集群模式支持不好, 常用 多對'Master-Slave' 模式,開源版本需手動切換Slave變成Master 天然的‘Leader-Slave’無狀態集群,每臺服務器既是Master也是Slave 不支持
管理界面 一般 較好 一般

RabbitMQ

  • 可以支撐高并發、高吞吐量、性能很高,同時有非常完善便捷的后臺管理界面可以使用,

  • 另外,他還支持集群化、高可用部署架構、訊息高可靠支持,功能較為完善,

  • RabbitMQ的開源社區很活躍,較高頻率的版本迭代,來修復發現的bug以及進行各種優化,因此綜合考慮過后,公司采取了RabbitMQ,

  • RabbitMQ也有一點缺陷,就是他自身是基于erlang語言開發的,所以導致較為難以分析里面的原始碼,也較難進行深層次的原始碼定制和改造,需要較為扎實的erlang語言功底,

RocketMQ

  • 開源的,經過阿里生產環境的超高并發、高吞吐的考驗,性能卓越,同時還支持分布式事務等特殊場景,

  • RocketMQ是基于Java語言開發的,適合深入閱讀原始碼,有需要可以站在原始碼層面解決線上問題,包括原始碼的二次開發和改造,

Kafka

  • Kafka提供的訊息中間件的功能明顯較少一些,相對上述幾款MQ中間件要少很多,

  • Kafka的優勢在于專為超高吞吐量的實時日志采集、實時資料同步、實時資料計算等場景,

  • Kafka在大資料領域中配合實時計算技術(比如Spark Streaming、Storm、Flink)使用的較多,但是在傳統的MQ中間件使用場景中較少采用,

選型建議

RabbitMQ, erlang 語言阻止了大量的 Java 工程師去深入研究和掌控它,對公司而言,幾乎處于不可控的狀態,但是確實人家是開源的,比較穩定的支持,活躍度也高;
RocketMQ, 越來越多的公司會去用 RocketMQ,確實很不錯,畢竟是阿里出品,但社區可能有突然黃掉的風險(目前 RocketMQ 已捐給 Apache,但 GitHub 上的活躍度其實不算高)對自己公司技術實力有絕對自信的,推薦用 RocketMQ


中小型公司,技術實力較為一般,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,用 RocketMQ 是很好的選擇
如果是大資料領域的實時計算、日志采集等場景,用 Kafka 是業內標準的,絕對沒問題,社區活躍度很高,絕對不會黃,何況幾乎是全世界這個領域的事實性規范

MQ 有哪些常見問題?ranbbitMQ如何解決這些問題?

MQ 有哪些常見問題?

訊息的順序問題

訊息有序指的是可以按照訊息的發送順序來消費,

假如生產者產生了 2 條訊息:M1、M2,假定 M1 發送到 S1,M2 發送到 S2,要保證 M1 先于 M2 被消費順序,
image

訊息的重復問題

造成訊息重復的常見原因是:網路不可達,重試機制造成,
所以解決這個問題的辦法就是繞過這個問題,那么問題就變成了:如果消費端收到兩條一樣的訊息,應該怎樣處理?

訊息積壓

由于消費者速率遠低于生產者,或者是消費者宕機,訊息中間件中有大量訊息積壓到佇列中

rabbitMQ如何解決這些問題?

rabbitMQ解決訊息的順序方案

RabbitMQ:拆分多個 queue,每個 queue 一個 consumer,就是多一些 queue 而已,確實是麻煩點;或者就一個 queue 但是對應一個 consumer,然后這個 consumer 內部用記憶體佇列做排隊,然后分發給底層不同的 worker 來處理,
image


缺陷

  • 并行度就會成為訊息系統的瓶頸(吞吐量不夠)

  • 更多的例外處理,比如:只要消費端出現問題,就會導致整個處理流程阻塞,我們不得不花費更多的精力來解決阻塞的問題,通過合理的設計或者將問題分解來規避,

  • 不關注順序的應用實際大量存在

  • 佇列無序并不意味著訊息無序,所以從業務層面來保證訊息的順序而不僅僅是依賴于訊息系統,是一種更合理的方式,

其他解決方案

  • 方案一:消費端使用redis存盤訊息記錄表,通過redis鎖,控制消費者按照順序消費,

  • 方案三:采用RocketMQ順序消費機制;(不建議使用,會降低系統吞吐量)

rabbitMQ解決訊息的重復問題方案

消費端處理訊息的業務邏輯需要保持冪等性,使用redis存盤訊息id作為日志表,只要保持冪等性,不管來多少條重復訊息,最后處理的結果都一樣,保證每條訊息都有唯一編號和redis添加一張日志表來記錄已經處理成功的訊息的 ID,如果新到的訊息 ID 已經在日志表中,那么就不再處理這條訊息,

rabbitMQ解決訊息積壓方案

出現訊息積壓的問題,首先要排除掉消費者宕機的問題,其次,再根據監控面板,觀察消費者和生產者消費訊息及生產訊息的速率,

  • 生產者速率增加:一般電商系統大促時,比較常見,往往的應對手段是擴容消費端的實體數或服務降級,
  • 消費者速率減少:檢查一下日志是否有大量的消費錯誤,或是消費執行緒卡死或是等待資源鎖死,
  • 速率無變化:可能是消費失敗導致的一條訊息反復消費,從而拖慢整個系統的消費速度

RabbitMQ訊息的可靠傳輸?訊息丟失怎么辦?

RabbitMQ提供了訊息確認機制來確保訊息的可靠傳輸
訊息訊息確認機制包括兩部分:生產者到訊息中間件,即訊息的發布確認,訊息中間件到消費者,即訊息的消費確認,

生產者的訊息確認機制

rabbit的生產者客戶端提供了訊息發布的回呼介面,一旦生產者訊息到交換機失敗,則會觸發回呼,同理,交換機到訊息佇列也有回呼介面,一旦交換機向訊息佇列投遞訊息失敗,則會觸發回呼,

    /**
     * 訊息->交換機 回呼函式
     * ack:true 發送成功 false: 發送失敗
     */
    private final RabbitTemplate.ConfirmCallback confirmCallback = (correlationData, ack, cause) -> {
    //可以增加補償機制
	if (!ack) {
            log.error("sendMsg:=======> Msg To Exchange Failed! Cause:{}", cause);
        }
    };

    /**
     * 交換機->訊息佇列 回呼函式
     * 發送失敗:觸發returnCallback回呼函式
     */
      private final RabbitTemplate.ReturnCallback returnCallback = (message, replyCode, replyText, exchange, routingKey) -> 
	   //可以增加補償機制
	  log.error("sendMsg:=======> Exchange To Queue Failed! Message:{} Exchange:{} RoutingKey:{} Replay:{}", message.toString(), exchange, routingKey, replyText);

消費者的訊息確認機制

rabbitMQ開啟手動確認訊息,消費端需要收到訊息之后,手動ack才可表示訊息消費成功,否則可以投遞到死信佇列或者訊息重試,

訊息佇列的持久化

還有一種常見情況是,我們經常會遇到需要重啟中間件,或者是中間件宕機的問題,那么就需要開啟訊息持久化,否則會發生訊息還沒來得及消費會丟失的問題,

  • 將queue的持久化標識durable設定為true,則代表是一個持久的佇列

  • 發送訊息的時候將deliveryMode=2

RabbitMQ高可用

rabbitMQ有三種模式:單機模式、普通集群模式、鏡像集群模式

  • 單機模式:就是部署一個rabbitMQ實體
  • 集群模式:意思就是在多臺機器上啟動多個 RabbitMQ 實體,每個機器啟動一個,你創建的 queue,只會放在一個 RabbitMQ 實體上,但是每個實體都同步 queue 的元資料(元資料可以認為是 queue 的一些配置資訊,通過元資料,可以找到 queue 所在實體),你消費的時候,實際上如果連接到了另外一個實體,那么那個實體會從 queue 所在實體上拉取資料過來,這方案主要是提高吞吐量的,就是說讓集群中多個節點來服務某個 queue 的讀寫操作,
  • 鏡像集群模式:這種模式,才是所謂的 RabbitMQ 的高可用模式,跟普通集群模式不一樣的是,在鏡像集群模式下,你創建的 queue,無論元資料還是 queue 里的訊息都會存在于多個實體上,就是說,每個 RabbitMQ 節點都有這個 queue 的一個完整鏡像,包含 queue 的全部資料的意思,然后每次你寫訊息到 queue 的時候,都會自動把訊息同步到多個實體的 queue 上,RabbitMQ 有很好的管理控制臺,就是在后臺新增一個策略,這個策略是鏡像集群模式的策略,指定的時候是可以要求資料同步到所有節點的,也可以要求同步到指定數量的節點,再次創建 queue 的時候,應用這個策略,就會自動將資料同步到其他的節點上去了,這樣的話,好處在于,你任何一個機器宕機了,沒事兒,其它機器(節點)還包含了這個 queue 的完整資料,別的 consumer 都可以到其它節點上去消費資料,壞處在于,第一,這個性能開銷也太大了吧,訊息需要同步到所有機器上,導致網路帶寬壓力和消耗很重!RabbitMQ 一個 queue 的資料都是放在一個節點里的,鏡像集群下,也是每個節點都放這個 queue 的完整資料,

鏡像集群節點圖
image
slave 會準確地按照 master 執行命令順序進行動作,故 slave 和 master 上維護的狀態應該也是相同的,如果master 由于某種原因宕機了,那么"資源最老"的slave會被提升為新的master,
根據slave 加入的時間排序,時間最長的 slave 即為"資歷最老",發送到鏡像佇列的所有的訊息會被同時發往 master 和所有的slave,如果此時 master 掛掉了,訊息還會在 slave 上,這樣 slave 提升為 master 的時候訊息也不會丟失


鏡像集群作業模式圖
image
除發送訊息(Basic.Publish)外的所有動作都只會向 master 發送,然后再由 master 將命令執行的結果廣播給各個 slave,如果消費者與 slave 建立連接并進行訂閱訊息,其實質上都是從 master 上獲取訊息,只不過看似是從 slave 上消費而已,比如:消費者與 slave 建立了 TCP 連接之后執行一個 Basic.GET 的操作,那么首先是由 slave 將 Basic.GET 請求發往 master,再由 master 準備好資料回傳給 slave,最后由 slave投遞給消費者,


轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/542637.html

標籤:架構設計

上一篇:阿里高級技術專家方法論:如何寫復雜業務代碼?

下一篇:認知篇:CQRS架構模式的本質

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more