進大廠必備的RocketMQ你會嗎?

於消息隊列,相信你們都不陌生,如今的中大型項目中或多或少都有使用到消息隊列,對於消息隊列你們可能都有必定的瞭解,使用消息隊列能夠解決什麼樣的問題,又會帶來哪些問題相信也有了解,在前邊的文章《消息隊列(一)》中有介紹,感興趣的小夥伴能夠點擊文章名直接打開。緩存

今天咱們主要介紹一下RocketMQ,關於RocketMQ不少人只知道是阿里開源的一款MQ中間件,實際工做中仍是用的RabblitMQ,本文以及接下來幾篇文章,我會分享一下RocketMQ相關的知識,詳細的介紹一下RocketMQ,但願能夠幫助到須要的朋友們。服務器

RocketMQ基本概念


  • Producer:消息生產者,負責生產消息,通常由業務系統負責生產消息,消息生產者把業務應用產生的消息發送到broker服務器,
  • Consumer:消息消費者,從broker服務器拉取消息或者接收broker推送的消息進行消費處理。
  • Broker:消息中轉的角色,負責存儲消息、轉發消息。
  • Name Server:充當路由消息的提供者,生產者或消費者能夠經過名字查找所需broker的IP列表,集羣部署的時候,各個NameServer實例是相互獨立的,沒有信息交換。
  • Topic:表示一類消息的集合,是RocketMQ進行消息訂閱的基本單位。
  • Message Queue:用於存儲消息的物理地址,每一個Topic中是消息地址存儲於多個Message Queue中。
  • Message:消息系統所傳輸信息的物理載體,生產和消費數據的最小單位,每條消息必須屬於一個主題。

RocketMQ的特性


RocketMQ的功能特性不少,這裏只簡單介紹幾個:網絡

  1. 順序消息

指的是能夠按照消息的發送順序來消費,有時候一組消息須要按照指定的順序消費纔有意義,可是多個消費者是並行消費的,RocketMQ能夠嚴格的保證消息的有序。順序消息能夠分爲兩類:全局順序消息和分區順序消息。全局順序是指某個topic下全部的消息都要保證順序,部分順序消息只要保證每一組消息被順序消費。架構

  • 全局順序消費:對於指定的一個Topic,全部的消息按照嚴格的先入先出的順序依次進行發佈和消費
  • 分區順序消費:對於指定的一個Topic,全部的消息根據sharding key進行區塊分區,同一個分區的消息按照先入先出的順序進行消費。性能較全局順序高。
  1. 事務消息

RocketMQ事務消息是指應用本地事務和發送消息操做能夠被定義在全局事務中,要麼同時成功,要麼同時失敗,RocketMQ的事務消息提供了相似X/Open XA的分佈式事務功能,經過事務消息能達到分佈式事務的最終一致性。負載均衡

  1. 定時消息

定時消息是指消息發送到broker後,不會當即消費,等到設定的設定的實際纔會投遞給真正的topic。broker有配置項messageDelayLevel,默認值有1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h,也能夠配置自定義的messageDelayLevel,在發送消息的時候,設置delayLevel等級便可:msg.setDelayLevel(level)異步

定時消息會暫存在名爲SCHEDULE_TOPIC_XXXX的topic中,並根據delayTimeLevel存入特定的queue,queueId = delayTimeLevel – 1,即一個queue只存相同延遲的消息,保證具備相同發送延遲的消息可以順序消費。broker會調度地消費SCHEDULE_TOPIC_XXXX,將消息寫入真實的topic。分佈式

  1. 回溯消息

回溯消息是指消費者以及消費成功,因爲業務須要,須要從新消費,若是要實現此功能,Broker在向消費者投遞成功消息後,消息仍然須要保留。從新消費通常是有必定時間緯度的,RocketMQ支持按照時間回溯消息,時間維度能夠精確到毫秒。ide

  1. 消息重投

生產者在發送消息時,同步消費失敗會重投,異步消息有重試,oneway沒有任何保證。消息重投能夠最大限度的保證消息發送成功、不丟失,可是也會致使消息重複,當消息量大、網絡很差的時候消息重複的機率就會提升。性能

咱們能夠根據須要設置消息重試策略:url

  • retryTimesWhenSendFailed:同步發送失敗重投次數,默認爲2 ,在重投的時候不會發送給上次失敗的broker,會嘗試向其餘的broker發送,儘量的保證消息不丟失。
  • retryTimesWhenSendAsyncFailed:異步發送失敗重試次數,異步的重試仍是選擇上次的broker,不會選擇其餘的broker,不能保證消息不丟失。
  • retryAnotherBrokerWhenNotStoreOK:消費刷盤超時或者slave不可用,是否嘗試發送給其餘的broker,默認爲false,很是重要的消息咱們能夠開啓。
  1. 死 信隊列

死信隊列用於處理消費失敗的消息,當消息消費失敗的時候,會自動進行消息重試,若是達到最大重試次數後,仍是沒有消費成功,就說明正常狀況下不能正確的消費該消息,此時消息隊列會把這個消息發送到該消費者對應的特殊隊列中。RocketMQ將這種消息稱爲死信消息,將這種存儲死信消息的隊列稱爲死信隊列,能夠經過console控制檯對死信隊列中的消息進行重發。

  1. 流量控制

生產者流控,通常是由於broker處理能力達到了上限。消費者流控,通常是由於消費者消費能力達到了上限。

生產者流控:

  • commitLog文件被鎖時間超過osPageCacheBusyTimeOutMills時,參數默認爲1000ms,返回流控。
  • 若是開啓transientStorePoolEnable == true,且broker爲異步刷盤的主機,且transientStorePool中資源不足,拒絕當前send請求,返回流控。
  • broker每隔10ms檢查send請求隊列頭部請求的等待時間,若是超過waitTimeMillsInSendQueue,默認200ms,拒絕當前send請求,返回流控。
  • broker經過拒絕send 請求方式實現流量控制。

生產者流控不會嘗試消息重投。

消費者流控:

  • 消費者本地緩存消息數超過pullThresholdForQueue時,默認1000。
  • 消費者本地緩存消息大小超過pullThresholdSizeForQueue時,默認100MB。
  • 消費者本地緩存消息跨度超過consumeConcurrentlyMaxSpan時,默認2000。

消費者流控會下降拉取頻率。

RocketMQ技術架構


以多Master多Slave模式爲例:

圖片

咱們能夠看到,RocketMQ架構上分爲四部分,分別爲Producer、Consumer、NameServer、Broker。
  • Producer:消息發佈的角色,支持分佈式集羣方式部署。Producer經過MQ的負載均衡模塊選擇相應的Broker集羣隊列進行消息投遞,投遞的過程支持快速失敗而且低延遲。
  • Consumer:消息消費的角色,支持分佈式集羣方式部署。支持以push推,pull拉兩種模式對消息進行消費。同時也支持集羣方式和廣播方式的消費,它提供實時消息訂閱機制,能夠知足大多數用戶的需求。
  • NameServer:NameServer是一個很是簡單的Topic路由註冊中心,其角色相似Dubbo中的zookeeper,支持Broker的動態註冊與發現。主要包括兩個功能:Broker管理,NameServer接受Broker集羣的註冊信息而且保存下來做爲路由信息的基本數據。而後提供心跳檢測機制,檢查Broker是否還存活;路由信息管理,每一個NameServer將保存關於Broker集羣的整個路由信息和用於客戶端查詢的隊列信息。而後Producer和Conumser經過NameServer就能夠知道整個Broker集羣的路由信息,從而進行消息的投遞和消費。NameServer一般也是集羣的方式部署,各實例間相互不進行信息通信。Broker是向每一臺NameServer註冊本身的路由信息,因此每個NameServer實例上面都保存一份完整的路由信息。當某個NameServer因某種緣由下線了,Broker仍然能夠向其它NameServer同步其路由信息,Producer,Consumer仍然能夠動態感知Broker的路由的信息。
  • Broker:Broker主要負責消息的存儲、投遞和查詢以及服務高可用保證,爲了實現這些功能,Broker包含了如下幾個重要子模塊。

RocketMQ部署架構


以多Master多Slave模式爲例:

圖片

集羣的工做流程;

  • 啓動NameServer,NameServer起來後監聽端口,等待Broker、Producer、Consumer連上來,至關於一個路由控制中心。
  • Broker啓動,跟全部的NameServer保持長鏈接,定時發送心跳包。心跳包中包含當前Broker信息(IP+端口等)以及存儲全部Topic信息。註冊成功後,NameServer集羣中就有Topic跟Broker的映射關係。
  • 收發消息前,先建立Topic,建立Topic時須要指定該Topic要存儲在哪些Broker上,也能夠在發送消息時自動建立Topic。
  • Producer發送消息,啓動時先跟NameServer集羣中的其中一臺創建長鏈接,並從NameServer中獲取當前發送的Topic存在哪些Broker上,輪詢從隊列列表中選擇一個隊列,而後與隊列所在的Broker創建長鏈接從而向Broker發消息。
  • Consumer跟Producer相似,跟其中一臺NameServer創建長鏈接,獲取當前訂閱Topic存在哪些Broker上,而後直接跟Broker創建鏈接通道,開始消費消息。

今天的分享暫時告一段落,後邊還有多篇文章繼續分享,理論分享結束會有一個demo來演示各個場景。

相關文章
相關標籤/搜索