MQ的優點和缺點?
優點:解耦 異步,削峰
解耦:
所以需要用來解耦:
異步:
解決方法:
削峰:
解決方法是:
缺點:降低高可用性.增加系統的復雜程度.一致性問題
降低高可用的原因:系統引入的外部依賴越多,越容易掛掉,本來你就是A系統調用BCD三個系統的接口就好了,現在又加入一個mq,萬一mq掛掉了,整個系統也就崩潰了.
增加系統的復雜程度:硬生生的增加一個MQ進來怎么保證不被重復消費?怎么保證不會出現消息丟失的情況?怎么保證消息傳遞的順序性?
一致性問題:系統A處理完以后直接返回成功了,人家都認為你這個請求成功了,但問題是,要是BCD三個系統成功了,結果C系統寫庫失敗了,咋整?數據就不一致了.
如果發生丟消息的時候怎么解決?
采用持久化訂閱的方式,防止消息的丟失 PTP模式,持久化是不會丟失消息的.
同時還可以采用mq手動簽到的方式,client真的接收到了消息,才簽到,否則就不能簽到,直接接收再簽到.
怎么保證MQ不會重復發送消息?
采用的是一張表來記錄消息處理的狀態,在處理MQ發送的消息的時候,我先查看一下這張表,是不是處理過相同的消息.如果發送過,就不在發送.
MQ重復消費的問題
1.首先產生mq重復消費的問題的原因
1.1 首先假如生產者生產數據,生產的數據都有一個offset標號,代表這個數據消費的順序的序號
1.2 例如生產者生產了三條消息152,153,154,這時發送到mq,
1.3 mq按照順序將數據提交到消費者
1.4 消費者是定時將消費的數據記錄提交到zookeeper zk中記錄了現在消費到第幾條數據,告訴mq
1.5 如果此時消費了152,153消費者重啟了,那么記錄沒提交到zk,此時mq以為消費者才消費到151,還會重新提交152,153
1.6 此時數據就出現了重復的問題,數據庫就出現了臟數據
2.如何解決mq的重復消費問題
2.1 重復消費的問題會導致數據庫出現臟數據,我們一般通過保證冪等性來解決這個問題
2.2 冪等性是什么。一次和多次請求某一個資源對於資源本身應該具有同樣的結果。如何保證生產者重復消費數據保證冪等性
2.3 有多種方式實現。最簡單的在插入數據庫的數據加個唯一健,這樣你插入相同的數據的時候只會保錯,不會出現臟數據
2.4 在redis中存個id,每次操作數據之前查下id是否存在。存在的話就不做處理,不存在的話,我們就操作數據庫。這樣解決冪等性問題
mq消息的順序是怎么進行保證的?
消息被發送的時候保持順序
消息被存儲的時候保持和發送的順序的一致
消息被消費的時候保持和存儲的消息順序一致.
kafka、activemq、rabbitmq、rocketmq都有什么優缺點?
1. 引入消息隊列之后如何保證其高可用性?
(1)RabbitMQ的高可用性
RabbitMQ是比較有代表性的,因為是基於主從做高可用性的,我們就以他為例子講解第一種MQ的高可用性怎么實現。
rabbitmq有三種模式:單機模式,普通集群模式,鏡像集群模式
(1.1) 單機模式
就是demo級別的,一般就是你本地啟動了玩玩兒的,沒人生產用單機模式
(1.2)普通集群模式
意思就是在多台機器上啟動多個rabbitmq實例,每個機器啟動一個。但是你創建的queue,只會放在一個rabbtimq實例上,但是每個實例都同步queue的元數據。完了你消費的時候,實際上如果連接到了另外一個實例,那么那個實例會從queue所在實例上拉取數據過來。
這種方式確實很麻煩,也不怎么好,沒做到所謂的分布式,就是個普通集群。因為這導致你要么消費者每次隨機連接一個實例然后拉取數據,要么固定連接那個queue所在實例消費數據,前者有數據拉取的開銷,后者導致單實例性能瓶頸。
而且如果那個放queue的實例宕機了,會導致接下來其他實例就無法從那個實例拉取,如果你開啟了消息持久化,讓rabbitmq落地存儲消息的話,消息不一定會丟,得等這個實例恢復了,然后才可以繼續從這個queue拉取數據。
所以這個事兒就比較尷尬了,這就沒有什么所謂的高可用性可言了,這方案主要是提高吞吐量的,就是說讓集群中多個節點來服務某個queue的讀寫操作。