RabbitMQ 淺析之一次隊列積壓

文章主要是兩部分,第一部分介紹 RabbitMQ 的基礎信息,網上有很多,如果對 RabbitMQ 比較熟悉可以略過,第二部分主要講述遇到的問題和影響性能的一些因素以及解決辦法。

第一部分

RabbitMQ 基礎介紹

RabbitMQ 是基于 Erlang 語言實現 AMQP(高級消息隊列協議)的消息中間件的一種,最初起源于金融系統,用于在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。

RabbitMQ 主要是為了實現系統之間的雙向解耦而實現的,消息的發送者無需知道消息使用者的存在,反之亦然。

一些 RabbitMQ 術語

  • Channel
  • Producer
  • Exchange
  • Queue
  • Consumer

數據流

data flow

Channel

客戶端和服務建立連接,通過 Channel 向 Exchange 發送消息,Exchange 通過 Routing Key 將消息路由到 Queue (Exchange 和 Queue 通過 Routing Key 建立綁定關系,Routing Key 也可以為空)。

Exchange (交換機)

接收消息且轉發消息到綁定隊列,Producer 只能將消息發給 Exchange,由 Exchange 將消息轉發到綁定的 Queue,Exchange 常用的幾種類型工作模式,fanout、direct、topic。

fanout 模式即為廣播模式,Exchange 會把同一份消息發送給所有的綁定隊列,每一個隊列收到的消息是相同的。
fanout.png

生產者 P 通過 Exchange X 將消息發給兩個隊列,C1、C2 分別消費對應的隊列,他們得到的數據是相同的。

direct 模式通過 RoutingKey 將消息發送給指定的隊列
direct.png

生產者 P 通過 Exchange X 將 error 消息發送到 amqp.gen-S9b 隊列,將 info、error、warning 消息發送到 amqp.gen-A1 隊列,他們分別對應著消費者 C1、C2。

topic 模式按照規則轉發,跟 direct 差不多,只是但是支持模式匹配,通配符等,具有更好的靈活性。
topic.png

topic 模式下,會對 Routing key 做模式匹配,* 代表匹配一個單詞,# 匹配 0 個或多個,*.orange.* 會把指定 Routing key 中間是 orange 的全部路由到 Q1 隊列,而 lazy.# 會把是 lazy. 開頭的消息分發到 Q2 隊列,*.*.rabbit 則代表把前兩個是任意詞,但是結尾是 .rabbit 的消息分發到 Q2 隊列。

交換機的幾個屬性
  • Durabilty 是否持久化
  • Auto Delete 是否自動刪除

Queue(隊列)

隊列是通過 RoutingKey 和 Exchange 綁定在一起的,Queue 的消息都來自 Exchange,Producer 是無法直接像隊列發送消息的,一個隊列可以和多個 Exchange 綁定在一起。

Queue 的幾個屬性

  • Durabilty
  • Auto Delete

第二部分

問題:通過 MQ 監控管理后臺發現隊列積壓嚴重,內存消耗 6G 多。
使用場景:移動端上報日志,存儲到 RabbitMQ,之后服務端消耗 MQ 對日志進行格式化后再次分發。

mq.png

注意上圖中的兩個紅色框處(當時沒有截圖),Consumer utilisation 當時在 7% 左右,Process memory 大約 6G 多,生產者每秒大約產生 2000 條消息,Consumer utilisation 代表了消費者的工作效率,一般效率低有幾種情況

  • 消費者太少
  • ACK 回執速度太慢
  • 消費者太多

首先我們沒有采用 ACK 機制,這樣就不存在這個問題,第二 Exchange 和 Queue 在建立的時候,采用了 fanout 模式并且持久化,持久化和非持久化大約有 10 倍的性能差異,如果只是單存的針對同一個隊列增加 Consumer,并不會改善效率,而 fanout 的廣播模式不利于增加多個 Queue。

解決辦法:重建了 Exchange 和 Queue,采用 direct 模式且非持久化的方式,對同一個 Exchange 綁定了 5 個 Queue,生產者隨機的將消息分發到某個隊列,每個 Queue 會對應一個消費者。因為消息本身是日志,日志有時間的,所以不存在時序的問題,這樣就大大的提高了消費者的工作效率,通過這樣的改進以后,Consomer utilisation 基本處在 100%,而且也沒有出現隊列積壓。

內存與流量控制參數

  • prefetch 是每次從一次性從 broker 里面取的待消費的消息的個數,值太大會增加延遲,太小會導致消息積壓。
  • vm_memory_high_watermark 內存流量控制,默認 0.4(還可以是絕對值),當占用物理內存的 40% 時,它會引起一個內存報警并且阻塞所有連接。 百分比情況下可使用內存 vm_memory_limit = vm_memory_high_watermark * 物理內存,絕對值情況下 vm_memory_limit = vm_memory_high_watermark。
$ rabbitmqctl status | grep vm_memory
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,40530786713},
  • vm_memory_high_watermark_paging_ratio 確定了何時執行消息從內存轉移到硬盤,默認 0.5,當內存消耗 vm_memory_limit * 0.5 時,開始從內存轉移到硬盤。

PS:
使用 RabbitMQ 時,創建 Exchange 和 Queue 要注意自己的使用場景,是否需要持久化,是否需要 ACK 機制,消息分發模式,是否有時序要求等等,千萬不要隨便建個 fanout 模式放那就用。

參考

https://www.rabbitmq.com/documentation.html
https://emacsist.github.io/tags/#rabbitmq
http://lynnkong.iteye.com/blog/1699684
https://www.gitbook.com/book/geewu/rabbitmq-quick

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容

  • 來源 RabbitMQ是用Erlang實現的一個高并發高可靠AMQP消息隊列服務器。支持消息的持久化、事務、擁塞控...
    jiangmo閱讀 10,377評論 2 34
  • rabbitMQ是一款基于AMQP協議的消息中間件,它能夠在應用之間提供可靠的消息傳輸。在易用性,擴展性,高可用性...
    點融黑幫閱讀 3,021評論 3 41
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,818評論 18 139
  • 關于消息隊列,從前年開始斷斷續續看了些資料,想寫很久了,但一直沒騰出空,近來分別碰到幾個朋友聊這塊的技術選型,是時...
    預流閱讀 585,295評論 51 786
  • 1. 歷史 RabbitMQ是一個由erlang開發的AMQP(Advanced Message Queue )的...
    高廣超閱讀 6,111評論 3 51