1. 程式人生 > >MQ的理論理解

MQ的理論理解

發送 遠程 支付系統 activemq rabbit 跳轉 ssa 結構 指向

MQ(消息隊列)簡介

概念 :
消息隊列(MQ)是一種應用程序對應用程序的通信方法。

應用程序通過寫和檢索出入列隊的針對應用程序的數據(消息)來通信,而無需專用連接來鏈接它們。

消息傳遞指的是程序之間通過在消息中發送數據進行通信,而不是通過直接調用彼此來通信,直接調用通常是用於諸如遠程過程調用的技術。

排隊指的是應用程序通過隊列來通信。隊列的使用除去了接收和發送應用程序同時執行的要求。

為什麽會需要消息隊列(MQ)?
主要原因是由於在高並發環境下,由於來不及同步處理,請求往往會發生堵塞,比如說,大量的insert,update之類的請求同時到達MySQL,直接導致無數的行鎖表鎖,甚至最後請求會堆積過多,從而觸發too many connections錯誤。通過使用消息隊列,我們可以異步處理請求,從而緩解系統的壓力。

MQ的特點

1 采用異步處理模式

消息發送者可以發送一個消息而無須等待響應。消息發送者將消息發送到一條虛擬的通道(主題或隊列)上,消息接收者則訂閱或是監聽該通道。一條信息可能最終轉發給一個或多個消息接收者,這些接收者都無需對消息發送者做出同步回應。整個過程都是異步的。

2 應用程序和應用程序調用關系為松耦合關系

主要體現在如下兩點:
(1)發送者和接受者不必了解對方、只需要確認消息
(2)發送者和接受者不必同時在線
比如在線交易系統為了保證數據的最終一致,在支付系統處理完成後會把支付結果放到消息中間件裏通知訂單系統修改訂單支付狀態。兩個系統通過消息中間件解耦。

MQ工作原理


首先來看本地通訊的情況,應用程序A和應用程序B運行於同一系統A,它們之間可以借助消息隊列技術進行彼此的通訊:應用程序A向隊列1發送一條信息,而當應用程序B需要時就可以得到該信息。

其次是遠程通訊的情況,如果信息傳輸的目標改為在系統B上的應用程序C,這種變化不會對應用程序A產生影響,應用程序A向隊列2發送一條信息,系統A的MQ發現Q2所指向的目的隊列實際上位於系統B,它將信息放到本地的一個特殊隊列-傳輸隊列(Transmission Queue)。我們建立一條從系統A到系統B的消息通道,消息通道代理將從傳輸隊列中讀取消息,並傳遞這條信息到系統B,然後等待確認。只有MQ接到系統B成功收到信息的確認之後,它才從傳輸隊列中真正將該信息刪除。如果通訊線路不通,或系統B不在運行,信息會留在傳輸隊列中,直到被成功地傳送到目的地。這是MQ最基本而最重要的技術--確保信息傳輸,並且是一次且僅一次(once-and-only-once)的傳遞。

MQ消息傳遞方式

發布訂閱模式

發布者/訂閱者模型支持向一個特定的消息主題生產消息。0或多個訂閱者可能對接收來自特定消息主題的消息感興趣。在這種模型下,發布者和訂閱者彼此不知道對方。這種模式就好比是匿名公告板。這種模式被概況為:多個消費者可以獲得消息,在發布者和訂閱者之間存在時間依賴性。發布者需要建立一個訂閱(subscription),以便能夠消費者訂閱。訂閱者必須保持持續的活動狀態及接收消息,除非訂閱者建立了持久的訂閱。在這種情況下,在訂閱者未連接時發布的消息將在訂閱者重新連接時重新發布。

點對點模式

點對點模型用於消息生產者和消息消費者之間點到點的通信。

消息生產者將消息發送到由某個名字標識的特定消費者。這個名字實際上對於消費服務中的一個隊列(Queue),在消息傳遞給消費者之前它被存儲在這個隊列中。

隊列消息可以放在內存中也可以是持久的,以保證在消息服務出現故障時仍然能夠傳遞消息。

MQ的應用場景

異步處理
場景說明:用戶註冊後,需要發註冊郵件和註冊短信。傳統的做法有兩種 1.串行的方式;2.並行方式
a、串行方式:將註冊信息寫入數據庫成功後,發送註冊郵件,再發送註冊短信。以上三個任務全部完成後,返回給客戶端。

b、並行方式:將註冊信息寫入數據庫成功後,發送註冊郵件的同時,發送註冊短信。以上三個任務完成後,返回給客戶端。與串行的差別是,並行的方式可以提高處理的時間

假設三個業務節點每個使用50毫秒鐘,不考慮網絡等其他開銷,則串行方式的時間是150毫秒,並行的時間可能是100毫秒。
因為CPU在單位時間內處理的請求數是一定的,假設CPU1秒內吞吐量是100次。則串行方式1秒內CPU可處理的請求量是7次(1000/150)。並行方式處理的請求量是10次(1000/100)
小結:如以上案例描述,傳統的方式系統的性能(並發量,吞吐量,響應時間)會有瓶頸。如何解決這個問題呢?

引入消息隊列,將不是必須的業務邏輯,異步處理。改造後的架構如下:

按照以上約定,用戶的響應時間相當於是註冊信息寫入數據庫的時間,也就是50毫秒。註冊郵件,發送短信寫入消息隊列後,直接返回,因此寫入消息隊列的速度很快,基本可以忽略,因此用戶的響應時間可能是50毫秒。因此架構改變後,系統的吞吐量提高到每秒20 QPS。比串行提高了3倍,比並行提高了兩倍。

2.2應用解耦
場景說明:用戶下單後,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。如下圖:



傳統模式的缺點:假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗,訂單系統與庫存系統耦合

如何解決以上問題呢?引入應用消息隊列後的方案,如下圖:

訂單系統:用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功
庫存系統:訂閱下單的消息,采用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操作
假如:在下單時庫存系統不能正常使用。也不影響正常下單,因為下單後,訂單系統寫入消息隊列就不再關心其他的後續操作了。實現訂單系統與庫存系統的應用解耦

2.3流量削鋒
流量削鋒也是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。
應用場景:秒殺活動,一般會因為流量過大,導致流量暴增,應用掛掉。為解決這個問題,一般需要在應用前端加入消息隊列。
a、可以控制活動的人數
b、可以緩解短時間內高流量壓垮應用

用戶的請求,服務器接收後,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接拋棄用戶請求或跳轉到錯誤頁面。
秒殺業務根據消息隊列中的請求信息,再做後續處理

2.4日誌處理
日誌處理是指將消息隊列用在日誌處理中,比如Kafka的應用,解決大量日誌傳輸的問題。架構簡化如下

日誌采集客戶端,負責日誌數據采集,定時寫受寫入Kafka隊列
Kafka消息隊列,負責日誌數據的接收,存儲和轉發
日誌處理應用:訂閱並消費kafka隊列中的日誌數據

常見的消息隊列

1)ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線;

2)RabbitMQ 是由 LShift 提供的一個 Advanced Message Queuing Protocol (AMQP) 的開源實現,由以高性能、健壯以及可伸縮性出名的 Erlang 寫成,因此也是繼承了這些優點。;

3)kafka 是一種高吞吐量的分布式發布訂閱消息系統,她有如下特性:

  • 通過O(1)的磁盤數據結構提供消息的持久化,這種結構對於即使數以TB的消息存儲也能夠保持長時間的穩定性能。
  • 高吞吐量:即使是非常普通的硬件kafka也可以支持每秒數十萬的消息。
  • 支持通過kafka服務器和消費機集群來分區消息。
  • 支持Hadoop並行數據加載。

4)ZeroMQ是一個輕量級消息內核。它可用於C、C++、Python、.NET /Mono、Fortran和Java語言。它運行在AIX , FreeBSD的,基於HP - UX , Linux和MacOS下, OpenBSD系統, OpenVMS , QNX Neutrino, Solaris和Windows操作系統。

MQ的理論理解