- 解耦
>> 下降系統耦合度
複製代碼
- 異步
>> 提高系統響應速度
複製代碼
- 削峯
>> 抵抗請求高峯時期
複製代碼
爲何使用消息隊列?消息隊列有什麼優勢和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優勢和缺點?git
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
單機吞吐量 | 萬級 | 萬級 | 十萬級,支持高吞吐 | 十萬級,支持高吞吐 |
時效性 | ms級 | 微秒級 | ms級 | ms級之內 |
可用性 | 高可用(基於主從架構) | 高可用(基於主從架構) | 高可用 分佈式架構 | 高可用,分佈式,一個數據多個副本 |
消息可靠性 | 有較低機率丟失 | 基本不丟 | 參數配置可作到0丟失 | 參數配置能夠作到0丟失 |
功能支持 | 沒通過大規模吞吐量場景的驗證,社區也不是很活躍 | 基於 erlang 開發,併發能力很強,性能極好,延時很低,開源,比較穩定的支持,活躍度也高; | 功能較爲完善,仍是分佈式的,擴展性好 | 功能較爲簡單,主要支持簡單的 MQ 功能,在大數據領域的實時計算以及日誌採集被大規模使用,社區活躍度很高 |
綜上,各類對比以後,有以下建議:
最先你們都用 ActiveMQ,可是如今確實你們用的很少了,沒通過大規模吞吐量場景的驗證,社區也不是很活躍;
後來你們開始用 RabbitMQ,可是確實 erlang 語言阻止了大量的 Java 工程師去深刻研究和掌控它,對公司而言,
幾乎處於不可控的狀態,可是確實人家是開源的,比較穩定的支持,活躍度也高;
不過如今確實愈來愈多的公司會去用 RocketMQ,確實很不錯,畢竟是阿里出品,
但社區可能有忽然黃掉的風險(目前 RocketMQ 已捐給 Apache,但 GitHub 上的活躍度其實不算高)對本身公司
技術實力有絕對自信的,推薦用 RocketMQ,不然回去老老實實用 RabbitMQ 吧,人家有活躍的開源社區,
絕對不會黃。
因此中小型公司,技術實力較爲通常,技術挑戰不是特別高,
用 RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,用 RocketMQ 是很好的選擇。
若是是大數據領域的實時計算、日誌採集等場景,用 Kafka 是業內標準的,絕對沒問題,社區活躍度很高,
絕對不會黃,況且幾乎是全世界這個領域的事實性規範。
複製代碼
RabbitMQ 能夠開啓鏡像集羣模式,在鏡像集羣模式下, 你建立的 queue,不管元數據仍是 queue 裏的消息都會存在於多個實例上, 就是說,每一個 RabbitMQ 節點都有這個 queue 的一個完整鏡像, 包含 queue 的所有數據的意思。而後每次你寫消息到 queue 的時候, 都會自動把消息同步到多個實例的 queue 上。github
點擊查看更多詳細解答數據庫
首先你的明白重複消費會出現什麼問題,爲何要保證冪等性。舉個例子: 若是消費者乾的事兒是拿一條數據就往數據庫裏寫一條,你可能就把數據在數據庫裏插入了 2 次, 那麼數據就錯了。其實重複消費不可怕, 可怕的是你沒考慮到重複消費以後,怎麼保證冪等性。 解決: 每一個消息加一個全局惟一的序號,根據序號判斷這條消息是否處理過, 而後再根據本身的業務場景進行處理。或更新或丟棄。架構
- 消息生產者把消息搞丟了: RabbitMQ開啓 confirm 模式,若是寫入了 RabbitMQ 中,RabbitMQ 會給你回傳一個 ack 消息, 告訴你說這個消息 ok 了。 若是 RabbitMQ 沒能處理這個消息,會回調你的一個 nack 接口,告訴你這個消息接收失敗,你能夠重試。 並且你能夠結合這個機制本身在內存裏維護每一個消息id的狀態, 若是超過必定時間還沒接收到這個消息的回調,那麼你能夠重發。
- MQ本身搞丟了數據: RabbitMQ能夠開啓持久化
- 消費端丟失了數據: RabbitMQ默認是自動ack的,也就是說消息到了消費端,就會自動確認已經消費了這條消息, 這時候可能你消費端剛拿到數據,而後掛了,那這條消息不就丟失了。 關閉RabbitMQ的自動確認,每次消費端邏輯處理完的時候, 在程序裏確認消費完成,通知MQ,這樣就保證了在消費端不會丟失了
- RabbitMQ: 拆分多個 queue,每一個 queue 一個 consumer,就是多一些 queue 而已,確實是麻煩點; 或者就一個 queue 可是對應一個 consumer
- Kafka: 一個 topic,一個 partition,一個 consumer,內部單線程消費,單線程吞吐量過低, 通常不會用這個。 寫 N 個內存 queue,具備相同 key 的數據都到同一個內存 queue;而後對於 N 個線程, 每一個線程分別消費一個內存 queue 便可,這樣就能保證順序性。
點擊查看更多詳細解答分佈式
這種問題出現通常就是消費端出現問題了,致使大量消息積壓。 解決辦法: 修復consumer,恢復其消費能力,而後等待consumer消費完。 什麼?等待過久了? 消息積壓到幾百萬到上千萬數據時,那就有點蛋疼了,確實要好幾個小時,那就再提供一種解決方案 先修復 consumer 的問題,確保其恢復消費速度,而後新建一個 topic,partition 是原來的 10 倍,臨時創建好原先 10 倍的 queue 數量。 而後寫一個臨時的分發數據的 consumer 程序,這個程序部署上去消費積壓的數據, 消費以後不作耗時的處理,直接均勻輪詢寫入臨時創建好的 10 倍 數量的 queue。接着臨時徵用 10 倍的機器來部署consumer,每一批consumer消費一個臨時queue的數據。 這種作法至關因而臨時將 queue 資源 和 consumer 資源擴大 10 倍,以正常的 10倍速度來消費數據。等快速消費完積壓數據以後, 得恢復原先部署的架構,從新用原先的 consumer 機器來消費消息 如何處理消息過時失效問題 消息失效這沒得辦法了呀,只能怪當初設置失效時間的時候沒考慮到這個問題了, 可有可無的還好,要是重要的相似於訂單相關方面的消息,能夠寫個臨時程序, 根據訂單號把丟失的相關消息全查出來,補上。性能
點擊查看更多詳細解答大數據