1. MQ的優缺點 優點: 解耦:通過MQ解除上游系統和下游系統的調用耦合,下游系統只需要做消息的訂閱和取消訂閱,上游系統無需任何改動。(一生產,多消費的典型場景) 非同步:通過MQ將一些不需要同步獲取執行的結果,並且非常耗時的調用操作通過MQ非同步化。 削峰:通過MQ將一些高峰期的高併發流量積壓在MQ ...
1. MQ的優缺點
優點:
- 解耦:通過MQ解除上游系統和下游系統的調用耦合,下游系統只需要做消息的訂閱和取消訂閱,上游系統無需任何改動。(一生產,多消費的典型場景)
- 非同步:通過MQ將一些不需要同步獲取執行的結果,並且非常耗時的調用操作通過MQ非同步化。
- 削峰:通過MQ將一些高峰期的高併發流量積壓在MQ中,下游可以按自己的消費能力消費,不會出現過載消費的情況。
缺點:
- 可用性降低:如果MQ出現了問題,依賴MQ環節的服務都會出現癱瘓
- 複雜性提高:給系統引入額外的組件,調用鏈變長,變複雜。同時需要考慮的事情會變多(消息冪等,丟失,積壓等等)
- 數據一致性:下游服務執行部分失敗,導致數據不一致
2. MQ的選型
Kafka:
- 吞吐量:10w級別,吞吐量是Kafka最大的優點。
- 時效性:ms以內
- Topic數量對吞吐量的影響:topic達到幾百上千,吞吐量有較小幅度下降
- 應用場景:主要用於大數據做日誌採集,實時數據計算等場景。
- 高可用性:分散式系統架構,
- 優劣勢:功能簡單,但是吞吐量大,並且天然適合大數據採集和計算
RocketMQ:
- 吞吐量:10w級別,
- 時效性:ms
- Topic數量對吞吐量的影響:topic達到幾百上千,吞吐量有較小幅度下降
- 應用場景:吞吐量大的業務場景
- 高可用性:分散式系統架構,易擴展
- 優劣勢:介面移動,阿裡開源,有大規模的應用,社區活躍度高,可靠性ok
RabbitMQ:
- 吞吐量:萬級,比kafka和RocketMQ低了一個量級
- 時效性:微秒級別,延遲最低
- 應用場景:
- 高可用性:主從架構實現高可用
- 優劣勢:erlang開發,時效性極好,開源版本提供的管理頁面友好,強大。實現的機制較重,吞吐量較低
ActiveMQ:
- 吞吐量:萬級,比kafka和RocketMQ低了一個量級
- 時效性:ms
- 應用場景:主要還是非同步和削峰
- 高可用性:主從架構實現高可用
- 優劣勢:較低概率可能會丟消息,同時開源社區不夠活躍,目前更新較慢,假設遇到問題會很難解決。
3. 如何保證MQ的高可用
RabbitMQ:
單機模式,普通集群模式(中心化的),鏡像集群模式(queue對等,實時性差,網路負載重,不可線性拓展)
Kafka:
分散式架構,有多個broker(master,slave)。比如一個topic,數據不是分佈在一臺機器上,利於水平拓展。同時提供多副本機制保證高可用,針對一個topic下的副本,只能寫入到leader,然後同步到follower。是中心化的。broker之間的協調是通過zk完成的,選出一個controller,然後決定每個partition的主從。
RocketMQ:
分散式架構,有多個broker。和kafka不同,針對一個topic,在每個broker上會有多個queue,消息的消費是針對queue的,消息的冗餘是通過主從複製,有同步複製和非同步。broker的協調是通過nameServer來完成的,不同於kafka,RocketMQ沒有選舉機制,因為broker對等,一個broker掛了則由其他的broker處理請求,相當於剔除了這個broker。
4. 如何保證消息的冪等性
產生重覆消費的可能性:
- 消費者重啟前沒提交消費到的數據index,可能會導致重覆消費
- 網路抖動導致消費確認消息沒到達MQ,可能會導致重覆消費
保證冪等的手段:
- 如果是mysql,可以通過主鍵或者唯一索引等保證。 如果是redis,可以通過key保證
- 給每個消息增加一個全局唯一的id,然後通過redis做冪等性判斷,這裡可能會涉及到redis的事務原子性
5. 如何保證消息的可靠性
RocketMQ
1>從producer的角度
- 預設是同步堵塞的方式,可以通過返回值確認消息投遞到了broker
- 如果是事務的方式,如果投遞失敗,會把消息存到commitLog中去
- 支持日誌索引,投遞不成功的消息可以通過提供的API查詢到
2>從broker的角度
- 消息是會同步到commitLog中的,就算broker宕機也是能載入出來的
- broker支持同步刷盤和非同步刷盤
- broker支持主從部署
3>從consumer的角度
- consumer在消息消費的時候會記錄成功消費消息或者已經發回到broker的offset
- consumer維護的offset是會持久化的,就算consumer和broker都掛了,重啟的時候,consumer會讀取offset在發送給broker
- consumer消費失敗的時候會重試,然後更新offset
6. 如何保證消息的消費順序
順序消息包含兩種類型:
分區順序:一個Partition內所有的消息按照先進先出的順序進行發佈和消費
全局順序:一個Topic內所有的消息按照先進先出的順序進行發佈和消費
RocketMQ:我們知道針對一個topic是會有多個queue的,所以首先需要保證順序消費的消息是發到同一個queue中的,通過提供的分區函數保證消息能夠丟到一個queue中就好。 但是這樣只能保證分區順序,全局順序的話那就是只有一個分區。
7. 消息隊列里積壓了很多消息怎麼辦
可以通過臨時擴容,增加消費者數量,排查原先消費者出現的問題