天天看點

消息隊列面試解析系列(一)-消息隊列(MQ)的意義(下)3 是否可利用共享記憶體、RDMA提高MQ性能?4 APP⇆網關–生産–>消息隊列–消費–>秒殺服務問題

2.2.1 優點

能根據下遊的處理能力自動調節流量,達到“削峰填谷”。

2.2.2 缺點

  • 增加系統調用鍊環節,導緻總體響應延時加長
  • 上下遊系統都要将同步調用改為異步消息,增加系統複雜度

有無簡單點流控方式?如果能預估秒殺服務的能力,就可用MQ實作個令牌桶,更簡單流控。

2.2.3 令牌桶控流原理

機關時間内隻發放固定數量的令牌到令牌桶,規定服務在處理請求前須先從令牌桶中拿個令牌,若令牌桶中無令牌,則拒絕請求。

這保證機關時間,能處理請求不超過發放令牌數量,達成流控。

實作也簡單,無需破壞原有調用鍊,隻要網關在處理APP請求時加個擷取令牌流程。

消息隊列面試解析系列(一)-消息隊列(MQ)的意義(下)3 是否可利用共享記憶體、RDMA提高MQ性能?4 APP⇆網關–生産–>消息隊列–消費–>秒殺服務問題

令牌桶可簡單地用一個有固定容量的消息隊列加一個“令牌發生器”來實作:令牌發生器按照預估的處理能力,勻速生産令牌并放入令牌隊列(如果隊列滿了則丢棄令牌),網關在收到請求時去令牌隊列消費一個令牌,擷取到令牌則繼續調用後端秒殺服務,如果擷取不到令牌則直接傳回秒殺失敗。

令牌桶可以用消息隊列實作,也可以用Redis實作,也可以寫一個簡單的令牌桶服務,原理是一樣的。

以上常用的使用消息隊列兩種進行流量控制的設計方法,可以根據各自的優缺點和不同的适用場景進行合理選擇。

2.3 服務解耦

比如新訂單建立時:

  1. 支付系統需要發起支付流程
  2. 風控系統需要稽核訂單的合法性
  3. 客服系統需要給使用者發短信告知使用者
  4. 經營分析系統需要更新統計資料;

這些訂單下遊系統都需實時獲得訂單資料。随業務發展,訂單下遊不斷變化,每個系統可能隻需訂單資料子集,訂單服務團隊不得不花精力,應對不斷增變下遊,不停修改訂單系統與下遊系統之間接口。任一下遊系統接口變更,都需訂單子產品重上線,對核心的訂單服務,這是不可接受的。

所有的電商都選擇用MQ解決類似的系統高耦合問題。

訂單服務在訂單變化時發送一條消息到MQ的一個主題Order,所有下遊系統都訂閱該主題,這樣每個下遊系統都可獲得一份實時完整訂單資料。

無論增加、減少下遊系統或是下遊系統需求如何變化,訂單服務無需更改,實作了訂單服務與下遊服務解耦。

優點

  • 可在子產品、服務、接口等不同粒度上實作解耦
  • 訂閱/消費模式也可在資料粒度上解耦

基于 Pub/Sub 釋出/訂閱模型實作的事件驅動

原來使用 ETL、HTTP 調用 API方式,現在使用 MQ 可定時任務去拉取資料。

再比如實作一個微服務系統間的觀察者模式。

實作事務的最終一緻性

比如使用 rabbitmq 和 rocketmq。

其他适用場景還有比如連接配接流計算任務和資料、将消息廣播給大量接收者。

在單體應用裡需要用隊列解決的,在分布式系統中大都可用MQ解決。

MQ适用場景還是很多的,如秒殺、發郵件、發短信、高并發訂單等。

注意

不适合 MQ 的場景

如銀行轉賬、電信開戶、第三方支付等。

關鍵還是要意識到消息隊列的優劣點,然後分析場景是否适用。

3 是否可利用共享記憶體、RDMA提高MQ性能?

如果你說的共享記憶體指的是PageCache,很多消息隊列都會用到,RDMA據我所知常見的幾種消息隊列應該都還沒有使用,像Kafka它在消費的時候,直接使用Zero Copy,資料直接從PageCache寫到NIC的緩沖區中,都不需要進入應用記憶體空間。

另外,現代的消息隊列瓶頸并不在本機記憶體資料交換這塊,主要還是受限于網卡帶寬或者磁盤的IO,像JMQ、Kafka這些消息隊列,都可以打滿萬兆網卡或者把磁盤的讀寫速度拉滿。

4 APP⇆網關–生産–>消息隊列–消費–>秒殺服務問題

4.1 海量請求都放在MQ,MQ整體容量如何衡量?

消息隊列不可能能存放無限的消息,消息隊列滿應該也會有拒絕政策,比如線程池的任務隊列,任務隊列滿,并且超過最大的線程池數,四種的拒絕政策。

實際上,隻要有足夠的磁盤容量,消息隊列确實可以存放無限的消息。像秒殺請求這種資料,峰值并發高,但總資料量并不是很大,是以,堆積在消息隊列中完全沒問題。

4.2 APP響應逾時,即網關超過一定的時間沒有傳回

消息還在任務隊列中,還是會被秒殺服務處理,這樣的話,傳回給APP秒殺失敗,但是秒殺服務已經消費了消息?難道是在網關做補償麼?如果連接配接已經斷開,将秒殺服務對此消息的處理做復原操作麼?

都按照秒殺失敗處理即可。

4.3 網關和秒殺服務是通過消息隊列進行通信,那響應消息也通過隊列進行傳回麼?

隊列中會有APP對應的位址比如IP之類的?那這樣的話,APP的海量連接配接都同時連接配接着網關,不是會有問題麼?

響應一般采用RPC來實作。逾時或者傳回秒殺結果之前,網關和APP确實要保持連接配接,這是HTTP協定決定的。至于網關能不能承受海量的APP連接配接,這個應該不用擔心,網關的作用就是用來抗海量連接配接的,它也會有各種方法來解決這個問題。

4.4 消息隊列應該也會做多備的政策?比如隊列消息的服務挂了,那些消息全部不見,這樣不是也會存在問題麼?

是的,大部分生産系統中的消息隊列要配置成叢集,確定可用性和資料可靠性,這個後面的課程我們會講。

  • 參考

    《消息隊列高手課》