消息隊列-RabbitMQ

1. 消息隊列

1.1 優缺點

答:總結爲:

優點:

  • 解耦。系統生產消息後,直接給MQ不用關心其他事務。
  • 異步。異步執行,提高吞吐量。發送者將消息發送給消息隊列後,不需要同步等待接收者處理完畢,而是可以進行其它操作。
  • 削峯。請求在MQ中,Server根據處理能力處理消息,緩解服務器壓力。

缺點:

  • 系統可用性降低。MQ掛了,整個系統通信GG。
  • 系統複雜度增加。加入MQ,引出一致性、傳輸可靠性、消息不被重複消費等等問題。
  • 一致性問題。A處理結束返回,BC寫庫成功,D失敗,數據不一致。

1.2 消息中間件

答:主要是ActiveMQ、RabbitMQ、RocketMQ和KafKa。

  • ActiveMQ:老技術,現在用得不多。
  • RabbitMQ:開源、社區活躍,中小型用這個。
  • RocketMQ:阿里開發,和Dubbo RPC框架很像。
  • Kafaka:專門做大數據。

1.3 MQ常見問題和解決思路

  1. 消息順序問題:讓消息按發送順序被消費。
  • 解決方法:保證生產者-MQ-消費者,一一對應。合理設計規避。
  • 缺陷問題:吞吐量不夠;耦合度太高。從業務層面保證消息順序。
  1. 消息重複問題:因爲網絡問題導致消費者收到兩條一樣的消息。
  • 解決方法:保證冪等性,即不管多少重複消息,最後處理結果還是一樣。通過唯一編號標識消息或者日誌表記錄去重

2. RabbitMQ

RabbitMQ是一款開源的、erLang編寫,基於AMQP(Advanced Message Queuing Protocol)的消息中間件。

2.1 基本概念

在這裏插入圖片描述

  • Producer(生產者):生產消息的一方(郵件投遞者);
  • Consumer(消費者):消費消息的一方(郵件收件人);
  • Broker:MQ服務器實體,一般認爲一個Server就是一個Broker;
  • Routing Key:路由鍵,指定消息的路由規則;
  • Exchange:消息交換器,根據路由鍵把消息分發到隊列中;
  • Queue:消息隊列容器,保存消息直到發送給消費者,每個消息可以投入到一個或多個隊列。;
  • Binding:綁定,把exchange和queue按照路由規則綁定起來;
  • VHost:理解爲虛擬broker(mini-RabbitMQ),擁有獨立的組件和權限系統,可以做到vhost範圍的用戶控制,所以一般應用於權限隔離。
  • Channel:消息通道,在客戶端的每個連接裏,可建立多個channel,每個channel代表一個會話任務。

由Exchange、Queue、RoutingKey三個才能決定一個從Exchange到Queue的唯一的線路

2.2 工作模式

2.2.1 Simple簡單收發

  1. 生產者生產消息,把消息放進隊列;
  2. 消費者監聽隊列消息,有就消費掉。

2.2.2 Work競爭資源

  1. 生產者生產消息,把消息放進隊列;
  2. 多個消費者監聽同一隊列,競爭消費,誰搶到誰就消費。
  3. 可能導致重複消費問題。

2.2.3 Publish/Subscribe共享資源

  1. 生產者將消息發給broker,由交換機轉發到隊列中;
  2. 每個消費者監聽自己的隊列。

2.2.4 routing路由模式

  1. 生產者將消息發給broker,指定路由規則,交換機根據路由key轉發到對於的消息隊列;
  2. 只有對應的消費者才能消費消息。

2.2.5 topic主題模式

  1. 基於路由模式的模糊匹配,*匹配多個單詞,#匹配一個單詞(類似sql的模糊查詢)

2.3 消息相關問題

2.3.1 消息順序性

答:通常可以用兩種方法:

  • 拆分爲多個queue,queue和consumer一對一
  • queue唯一consumer多個,consumer內部排隊分發

2.3.2 消息冪等性

答:解決思路就是,對消息做唯一標識,根據標識判斷是否被消費。

2.3.3 消息傳輸方式

答:RabbitMQ使用信道傳輸數據,信道基於TCP連接,但不受數量限制,一條TCP連接上信道能無上限。

2.3.4 消息確認模式

答:分爲兩種確認模式。

  1. 發送方確認模式
  • 消息被分配唯一ID,當消息投遞到隊列後,信道發送ack給生產者,出錯就發送nack。
  • 異步,在等待確認過程中仍能繼續發消息。
  1. 接收方確認模式
  • 消費者每接收一條消息就確認一次。當消息被確認,才從隊列中刪除。
  • 沒有超時機制。只要consumer連接不中斷,就認爲消費者一直在處理。

2.3.5 消息丟失

答:分爲三種情況。

  1. 生產者丟失消息
  • transaction事務機制:把消息的發送作爲一個事務,過程中有異常就回滾,發送成功就提交。
  • confirm模式:就是發送方消息確認模式。
  1. 消息隊列丟失消息
  • 一般都是在開啓持久化時發生。
  • 和confirm機制配合使用,在消息投遞隊列並持久化後,再返回ack。
  1. 消費者丟失消息
  • 消費者接收消息後,處理消息前,回覆MQ已收到。這時異常會導致消息丟失。
  • 修改爲手動確認消息。

2.3.6 消息積壓

答:處理方法是臨時擴容。將queue和consumer資源擴大10倍(申請10倍的空間建立queue和10倍的機器部署consumer),積壓消息消費完後,恢復原先架構。

2.3.7 消息失效

答:RabbitMQ能設置消息的TTL,一旦消息積壓過久到達TTL就會被自動清理。解決方案是手動批量重導,手動將丟失數據,查出來併發送到MQ中。

2.3.8 延遲隊列

消息/隊列 TTL + 死信隊列 DLX + Router轉發隊列

設置了TTL後,當消息在隊列中變成死信,就被轉發到其他隊列中。

2.4 集羣模式

答:RabbitMQ基於主從模式實現高可用,分爲普通集羣和鏡像集羣模式。

  1. 普通集羣模式
  • 在多臺機器上啓動多個RabbitMQ實例。queue放在一個實例A上,但每個實例都同步queue的元數據。
  • 消費時,若連接到另一個實例B,則實例B會從實例A上拉取數據。

總結:集羣的多個節點服務一個queue的讀寫操作

  1. 鏡像集羣模式
  • 每個RabbitMQ都有一個queue的完整鏡像。每次寫消息到queue時,自動把消息同步到多個實例上。
  • 好處是單點宕機不怕,有備份。壞處是開銷大。

2.5 交換器類型

  • fanout:把消息不做判斷全部放進隊列。用來廣播信息。
  • direct:把消息放進路由完全匹配的隊列中。用來處理優先級任務。
  • topic:路由模糊匹配。
  • header:利用消息的header屬性進行匹配。基本不用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章