1. 程式人生 > 其它 >1.MQ 的相關概念

1.MQ 的相關概念

目錄

1.MQ 的相關概念

1.1什麼是 MQ

MQ(message queue),從字面意思上看,本質是個佇列, FIFO 先入先出,只不過佇列中存放的內容是message 而已,還是一種跨程序的通訊機制,用於上下游傳遞訊息。在網際網路架構中, MQ 是一種非常常見的上下游"邏輯解耦 + 物理解耦"的訊息通訊服務。使用了 MQ 之後,訊息傳送上游只需要依賴 MQ,不用依賴其他服務。

訊息佇列(MQ)全稱Message Queue ,是一種應用程式對應用程式的通訊方法。

系統之間其他的資料交換通訊方式:

rpc、http請求、springcloud基於http的json格式、web service

1.2為什麼要用 MQ

1.2.1流量消峰

舉個例子,如果訂單系統最多能處理一萬次訂單,這個處理能力應付正常時段的下單時綽綽有餘,正常時段我們下單一秒後就能返回結果。但是在高峰期,如果有兩萬次下單作業系統是處理不了的,只能限制訂單超過一萬後不允許使用者下單。使用訊息佇列做緩衝,我們可以取消這個限制,把一秒內下的訂單分散成一段時間來處理,這時有些使用者可能在下單十幾秒後才能收到下單成功的操作,但是比不能下單的體驗要好。

削峰:一個系統訪問流量有高峰時期,也有低峰時期,比如說,中午整點有一個搶購活動等等。比如系統平時流量並不高,一秒鐘只有100多個併發請求,系統處理沒有任何壓力,一切風平浪靜,到了某個搶購活動時間,系統併發訪問了劇增,比如達到了每秒5000個併發請求,而我們的系統每秒只能處理2000個請求,那麼由於流量太大,我們的系統、資料庫可能就會崩潰。這時如果使用MQ進行流量削峰,將使用者的大量訊息直接放到MQ裡面,然後我們的系統去按自己的最大消費能力去消費這些訊息,就可以保證系統的穩定,只是可能要跟進業務邏輯,給使用者返回特定頁面或者稍後通過其他方式通知其結果。

1.2.2應用解耦

以電商應用為例,應用中有訂單系統、庫存系統、物流系統、支付系統。使用者建立訂單後,如果耦合呼叫庫存系統、物流系統、支付系統,任何一個子系統出了故障,都會造成下單操作異常。當轉變成基於訊息佇列的方式後,系統間呼叫的問題會減少很多,比如物流系統因為發生故障,需要幾分鐘來修復。在這幾分鐘的時間裡,物流系統要處理的記憶體被快取在訊息佇列中,使用者的下單操作可以正常完成。當物流系統恢復後,繼續處理訂單資訊即可,中單使用者感受不到物流系統的故障, 提升系統的可用性。

解耦:可以在多個系統之間進行解耦,將原本通過網路之間的呼叫的方式改為使用MQ進行訊息的非同步通訊,只要該操作不是需要同步的,就可以改為使用MQ進行不同系統之間的聯絡,這樣專案之間不會存在耦合,系統之間不會產生太大的影響,就算一個系統掛了,也只是訊息擠壓在MQ裡面沒人進行消費而已,不會對其他的系統產生影響。

未使用MQ情況:

使用MQ情況:

1.2.3非同步處理

有些服務間呼叫是非同步的,例如 A 呼叫 B, B 需要花費很長時間執行,但是 A 需要知道 B 什麼時候可
以執行完,以前一般有兩種方式, A 過一段時間去呼叫 B 的查詢 api 查詢。或者 A 提供一個 callback api,
B 執行完之後呼叫 api 通知 A 服務。這兩種方式都不是很優雅, 使用訊息匯流排,可以很方便解決這個問題,
A 呼叫 B 服務後,只需要監聽 B 處理完成的訊息,當 B 處理完成後,會發送一條訊息給 MQ, MQ 會將此
訊息轉發給 A 服務。這樣 A 服務既不用迴圈呼叫 B 的查詢 api,也不用提供 callback api。同樣 B 服務也不
用做這些操作。 A 服務還能及時的得到非同步處理成功的訊息。

非同步:加入一個操作設計到好幾個步驟,這些步驟之間不需要同步完成,比如客戶去建立了一個訂單,還要去客戶軌跡系統新增一條軌跡、去庫存系統更新庫存、去客戶系統修改客戶的狀態等等。這樣如果這個系統都直接進行呼叫,那麼將會產生大量的時間,這樣對於客戶是無法接收的;並且像新增客戶軌跡這種操作是不需要去同步操作的,如果使用MQ將客戶建立訂單時,將後面的軌跡、庫存、狀態等資訊的更新全都放到MQ裡面然後去非同步操作,這樣就可加快系統的訪問速度,提供更好的客戶體驗。

未使用MQ情況:

使用MQ情況:

MQ是消費者--生產者模型的一個典型的代表,一端往訊息佇列中不斷寫入訊息,而另一端可以讀取佇列中的訊息,RabbitMQ是MQ的一種,除此之外,還有RocketMQ,Kafka,ActiveMQ等。

訊息佇列MQ,主要是用來實現應用程式的非同步和解耦,同時也能起到訊息緩衝,訊息分發的作用。

RabbitMQ是一種開源的實現AMQP(高階訊息佇列協議)的訊息中介軟體,最初起源於金融系統,用於在分散式系統中儲存轉發訊息,RabbitMQ主要是為了實現系統之間的雙向解耦而實現的,當生產者大量產生資料時,消費者無法快速消費,那麼需要一箇中間層,儲存這個資料。

AMQP,即Advanced Message Queuing Protocol,高階訊息佇列協議,是應用層協議的一個開放標準,為面向訊息的中介軟體設計。

RabbitMQ是採用Erlang語言編寫,支援多種客戶端訪問,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等。

1.3MQ 的分類

1.3.1ActiveMQ

優點: 單機吞吐量萬級,時效性 ms 級,可用性高,基於主從架構實現高可用性,訊息可靠性較低的概率丟失資料
缺點:官方社群現在對 ActiveMQ 5.x 維護越來越少, 高吞吐量場景較少使用。

1.3.2Kafka

大資料的殺手鐗,談到大資料領域內的訊息傳輸,則繞不開 Kafka,這款為大資料而生的訊息中介軟體,以其百萬級 TPS 的吞吐量名聲大噪,迅速成為大資料領域的寵兒,在資料採集、傳輸、儲存的過程中發揮著舉足輕重的作用。目前已經被 LinkedIn, Uber, Twitter, Netflix 等大公司所採納。
優點: 效能卓越,單機寫入 TPS 約在百萬條/秒,最大的優點,就是吞吐量高。時效性 ms 級可用性非常高, kafka 是分散式的,一個數據多個副本,少數機器宕機,不會丟失資料,不會導致不可用,消費者採用 Pull 方式獲取訊息, 訊息有序, 通過控制能夠保證所有訊息被消費且僅被消費一次;有優秀的第三方Kafka Web 管理介面 Kafka-Manager;在日誌領域比較成熟,被多家公司和多個開源專案使用;功能支援:功能較為簡單,主要支援簡單的 MQ 功能,在大資料領域的實時計算以及日誌採集被大規模使用
缺點: Kafka 單機超過 64 個佇列/分割槽, Load 會發生明顯的飆高現象,佇列越多, load 越高,傳送訊息響應時間變長, 使用短輪詢方式,實時性取決於輪詢間隔時間, 消費失敗不支援重試; 支援訊息順序,但是一臺代理宕機後,就會產生訊息亂序, 社群更新較慢;

1.3.3RocketMQ

RocketMQ 出自阿里巴巴的開源產品,用 Java 語言實現,在設計時參考了 Kafka,並做出了自己的一些改進。被阿里巴巴廣泛應用在訂單,交易,充值,流計算,訊息推送,日誌流式處理, binglog 分發等場景。
優點:單機吞吐量十萬級,可用性非常高,分散式架構,訊息可以做到 0 丟失,MQ 功能較為完善,還是分散式的,擴充套件性好,支援 10 億級別的訊息堆積,不會因為堆積導致效能下降,原始碼是 java 我們可以自己閱讀原始碼,定製自己公司的 MQ
缺點: 支援的客戶端語言不多,目前是 java 及 c++,其中 c++不成熟;社群活躍度一般,沒有在 MQ核心中去實現 JMS 等介面,有些系統要遷移需要修改大量程式碼

1.3.4RabbitMQ

2007 年釋出,是一個在 AMQP(高階訊息佇列協議)基礎上完成的,可複用的企業訊息系統,是當前最主流的訊息中介軟體之一。
優點:由於 erlang 語言的高併發特性,效能較好; 吞吐量到萬級, MQ 功能比較完備,健壯、穩定、易用、跨平臺、 支援多種語言 如: Python、 Ruby、 .NET、 Java、 JMS、 C、 PHP、 ActionScript、 XMPP、 STOMP等,支援 AJAX 文件齊全;開源提供的管理介面非常棒,用起來很好用,社群活躍度高; 更新頻率相當高

https://www.rabbitmq.com/news.html

缺點:商業版需要收費,學習成本較高

1.3.5kafka、activemq、rabbitmq、rocketmq優點和缺點

特性 ActiveMQ RabbitMQ RocketMQ kafka
單機吞吐量 萬級,吞吐量比RocketMQ和kafka要低一個數量級 萬級,吞吐量比RocketMQ和kafka要低一個數量級 10萬級,RocketMQ也是可以支撐高吞吐的一種MQ 10萬級別,kafka最大優點就是吞吐量大,一般配合大資料類的系統來進行實時資料計算、日誌採集等場景。
topic數量對吞吐量的影響 topic可以達到幾百、幾千個的級別,吞吐量會有小幅度的下降。這是RocketMQ的一大優勢,可在同等數量機器下支撐大量的topic topic從幾十個到幾百個的時候,吞吐量會大幅下降。所以在同等機器數量下,kafka儘量保證topic數量不要過多。如果支撐大規模topic需要增加更多的機器
時效性 ms級 微秒級,這是rabbitmq的一大特點,延遲是最低的 ms級 延遲在ms級以內
可用性 高,基於主從架構實現可用性 高,基於主從架構實現可用性 非常高,分散式架構 非常高,kafka是分散式的,一個數據多個副本,少數機器宕機,不會丟失資料,不會導致不可用
訊息可靠性 有較低的概率丟失資料 經過引數優化配置,可以做到0丟失 經過引數配置,訊息可以做到零丟失
功能支援 MQ領域的功能及其完備 基於erlang開發,所以併發效能極強,效能極好,延時低 MQ功能較為完備,分散式擴充套件性好 功能較為簡單,主要支援加單MQ功能
優勢 非常成熟,功能強大,在業內大量公司和專案中都有應用 erlang語言開發,效能極好、延時很低,吞吐量萬級、MQ功能完備,管理介面非常好,社群活躍;網際網路公司使用較多 介面簡單易用,阿里出品有保障,吞吐量大,分散式擴充套件方便、社群比較活躍,支援大規模的topic、支援複雜的業務場景,可以基於原始碼進行定製開發 超高吞吐量,ms級的時延,極高的可用性和可靠性,分散式擴充套件方便
劣勢 偶爾有較低概率丟失訊息,社群活躍度不高 吞吐量較低,erlang語音開發不容易進行定製開發,叢集動態擴充套件麻煩 介面不是按照標準JMS規範走的,有的系統遷移要修改大量的程式碼,技術有被拋棄的風險 有可能進行訊息的重複消費
應用 主要用於解耦和非同步,較少用在大規模吞吐的場景中 都有使用 用於大規模吞吐、複雜業務中 在大資料的實時計算和日誌採集中被大規模使用,是業界的標準

綜上所述,總結如下:
一般業務系統要引入MQ,最早大家都用ActiveMQ,但現在用的不多了。沒有經過大規模吞吐場景的驗證,社群也不活躍,不推薦再使用。
後來大家開始用rabbitMQ,但是它是使用erlang語言開發的,如果不精通erlang,對公司而言,幾乎處於不可控的狀態,單其是開源的,社群活躍度高,擁有比較穩定的支援。
現在越來越多的公司開始使用RocketMQ,但是要小心被拋棄的風險。如果公司有實力自己去維護開發,推薦使用。否則還是選擇RabbitMQ。
如果實在大資料的實時計算、日誌採集等領域,用kafka是業界標準。

所以,對於中小型公司,技術實力一般的,應該用rabbitmq,對於大公司,基礎架構研發能力強大的,推薦使用RocketMQ。