1. 程式人生 > >使用MQ訊息佇列的優缺點

使用MQ訊息佇列的優缺點

前言

公司的專案一直都是在使用MQ的,但是由於使用的功能很簡單,所以一直都是知其然不知其所以然,作為一個程式猿有必要了解每一個使用的技術,為什麼使用它?它的優點是什麼?缺點是什麼?等等。。。

使用mq的好處

解耦與複用

系統A要傳送一個訊息到多個系統,如果此時每增加一個系統,系統A都需要通過修改原始碼來增加介面,此時耦合非常高,但是如果中間使用訊息佇列的話,系統只需要傳送一次到訊息佇列,別的系統就能複用該資訊,當增加或刪除系統呼叫介面的時候,不需要額外的更新程式碼。

非同步

使用者呼叫一個介面的時候,可能該介面呼叫了別的方法。例如:使用者註冊的時候,後臺可能需要呼叫:查詢資料庫,插入資料庫,傳送郵件,傳送使用者指南等等...

但是使用者可能並不需要後臺將所有的任務執行完畢,那麼此時在初入資料口後面加入mq佇列,使用者就能很快得到註冊成功的響應而去做一些別的事情。mq的機制又能保證最終的一致性,所以使用起來很安全很穩定。

消峰

何為消峰,就是當系統壓力過大的時候,讓系統壓力減小。如何做?

加入資料庫的讀寫每秒3000,在高峰期,系統的訪問達到了每秒10000。此時由於加入了訊息佇列,所以不會出現激增的訪問導致系統奔潰。
(注意,曉峰並不會讓使用者的等待時間減少,所以一般會跟非同步搭配來使用)

使用mq的缺點

增加了複雜度與降低了可用性

本來系統之間直接通行呼叫介面就行了,但是引入了mq導致系統的複雜度大大增加,並且如果mq掛掉了,那麼系統之間的通訊就中斷了,導致整個系統的全部掛掉。

一致性問題

A系統處理完了傳送到訊息對流後直接返回成功了,使用者以為你這個請求就成功了;但是問題是,其他系統消費該訊息後,如果當中有一個系統出現了問題,導致資料丟失。最後就會發生資料不一致等問題。

常見的mq的區別

特性 ActiveMQ RabbitMQ RocketMQ Kafka
單機吞吐量 萬級,吞吐量比RocketMQ和Kafka要低了一個數量級 萬級,吞吐量比RocketMQ和Kafka要低了一個數量級 10萬級,RocketMQ也是可以支撐高吞吐的一種MQ 10萬級別,這是kafka最大的優點,就是吞吐量高。一般配合大資料類的系統來進行實時資料計算、日誌採集等場景
topic數量對吞吐量的影響 topic可以達到幾百,幾千個的級別,吞吐量會有較小幅度的下降這是RocketMQ的一大優勢,在同等機器下,可 topic可以達到幾百,幾千個的級別,吞吐量會有較小幅度的下降這是RocketMQ的一大優勢,在同等機器下,可
時效性 ms級 微秒級,這是rabbitmq的一大特點,延遲是最低的 ms級 延遲在ms級以內
可用性 高,基於主從架構實現高可用性 高,基於主從架構實現高可用性 非常高,分散式架構 非常高,kafka是分散式的,一個數據多個副本,少數機器宕機,不會丟失資料,不會導致不可用
訊息可靠性 有較低的概率丟失資料 經過引數優化配置,可以做到0丟失 經過引數優化配置,訊息可以做到0丟失
功能支援 MQ領域的功能極其完備 基於erlang開發,所以併發能力很強,效能極其好,延時很低 MQ功能較為完善,還是分散式的,擴充套件性好 功能較為簡單,主要支援簡單的MQ功能,在大資料領域的實時計算以及日誌採集被大規模使用,是事實上的標準
優劣勢總結 非常成熟,功能強大,在業內大量的公司以及專案中都有應用偶爾會有較低概率丟失訊息而且現在社群以及國內應用都越來越少,官方社群現在對ActiveMQ 5.x維護越來越少,幾個月才釋出一個版本而且確實主要是基於解耦和非同步來用的,較少在大規模吞吐的場景中使用 erlang語言開發,效能極其好,延時很低;吞吐量到萬級,MQ功能比較完備而且開源提供的管理介面非常棒,用起來很好用社群相對比較活的。RabbitMQ吞吐量會低一些,這是因為他做的實現機制比較重。erlang開發很難去看懂原始碼,你公司對這個東西的掌控很弱,基本職能依賴於開源社群的快速維護和修復bug。 介面簡單易用,而且畢竟在阿里大規模應用過,可以做到大規模吞吐,效能也非常好,分散式擴充套件也很方便,社群維護還可以,可靠性和可用性是ok的,還可以支撐大規模的topic數量。阿里出品都是java系的,我們可以自己閱讀原始碼。 kafka的特點其實很明顯,就是僅僅提供較少的核心功能,但是提供超高的吞吐量,ms級的延遲,極高的可用性以及可靠性,而且分散式可以任意擴充套件同時kafka最好是支撐較少的topic數量即可,保證其超高吞吐量而且kafka唯一的一點劣勢是有可能訊息重複消

總結

所以在軟體的正常功能開發中,並不需要去刻意的尋找訊息佇列的使用場景,而是當出現效能瓶頸時,去檢視業務邏輯是否存在可以非同步處理的耗時操作,如果存在的話便可以引入訊息佇列來解決。否則盲目的使用訊息佇列可能會增加維護和開發的成本卻無法得到可觀的效能提升,那就得不償失了。