active mq topic消费后删除_《我想进大厂》之MQ夺命连环11问
繼之前的mysql奪命連環之后,我發現我這個標題被好多套用的,什么奪命zookeeper,奪命多線程一大堆,這一次,開始面試題系列MQ專題,消息隊列作為日常常見的使用中間件,面試也是必問的點之一,一起來看看MQ的面試題。
你們為什么使用mq?具體的使用場景是什么?
mq的作用很簡單,削峰填谷。以電商交易下單的場景來說,正向交易的過程可能涉及到創建訂單、扣減庫存、扣減活動預算、扣減積分等等。每個接口的耗時如果是100ms,那么理論上整個下單的鏈路就需要耗費400ms,這個時間顯然是太長了。
如果這些操作全部同步處理的話,首先調用鏈路太長影響接口性能,其次分布式事務的問題很難處理,這時候像扣減預算和積分這種對實時一致性要求沒有那么高的請求,完全就可以通過mq異步的方式去處理了。同時,考慮到異步帶來的不一致的問題,我們可以通過job去重試保證接口調用成功,而且一般公司都會有核對的平臺,比如下單成功但是未扣減積分的這種問題可以通過核對作為兜底的處理方案。
使用mq之后我們的鏈路變簡單了,同時異步發送消息我們的整個系統的抗壓能力也上升了。
那你們使用什么mq?基于什么做的選型?
我們主要調研了幾個主流的mq,kafka、rabbitmq、rocketmq、activemq,選型我們主要基于以下幾個點去考慮:
基于以上幾個考慮,我們最終選擇了RocketMQ。
你上面提到異步發送,那消息可靠性怎么保證?
消息丟失可能發生在生產者發送消息、MQ本身丟失消息、消費者丟失消息3個方面。
生產者丟失
生產者丟失消息的可能點在于程序發送失敗拋異常了沒有重試處理,或者發送的過程成功但是過程中網絡閃斷MQ沒收到,消息就丟失了。
由于同步發送的一般不會出現這樣使用方式,所以我們就不考慮同步發送的問題,我們基于異步發送的場景來說。
異步發送分為兩個方式:異步有回調和異步無回調,無回調的方式,生產者發送完后不管結果可能就會造成消息丟失,而通過異步發送+回調通知+本地消息表的形式我們就可以做出一個解決方案。以下單的場景舉例。
一般而言,對于大部分場景來說異步回調的形式就可以了,只有那種需要完全保證不能丟失消息的場景我們做一套完整的解決方案。
MQ丟失
如果生產者保證消息發送到MQ,而MQ收到消息后還在內存中,這時候宕機了又沒來得及同步給從節點,就有可能導致消息丟失。
比如RocketMQ:
RocketMQ分為同步刷盤和異步刷盤兩種方式,默認的是異步刷盤,就有可能導致消息還未刷到硬盤上就丟失了,可以通過設置為同步刷盤的方式來保證消息可靠性,這樣即使MQ掛了,恢復的時候也可以從磁盤中去恢復消息。
比如Kafka也可以通過配置做到:
acks=all 只有參與復制的所有節點全部收到消息,才返回生產者成功。這樣的話除非所有的節點都掛了,消息才會丟失。 replication.factor=N,設置大于1的數,這會要求每個partion至少有2個副本 min.insync.replicas=N,設置大于1的數,這會要求leader至少感知到一個follower還保持著連接 retries=N,設置一個非常大的值,讓生產者發送失敗一直重試雖然我們可以通過配置的方式來達到MQ本身高可用的目的,但是都對性能有損耗,怎樣配置需要根據業務做出權衡。
消費者丟失
消費者丟失消息的場景:消費者剛收到消息,此時服務器宕機,MQ認為消費者已經消費,不會重復發送消息,消息丟失。
RocketMQ默認是需要消費者回復ack確認,而kafka需要手動開啟配置關閉自動offset。
消費方不返回ack確認,重發的機制根據MQ類型的不同發送時間間隔、次數都不盡相同,如果重試超過次數之后會進入死信隊列,需要手工來處理了。(Kafka沒有這些)
你說到消費者消費失敗的問題,那么如果一直消費失敗導致消息積壓怎么處理?
因為考慮到時消費者消費一直出錯的問題,那么我們可以從以下幾個角度來考慮:
那如果消息積壓達到磁盤上限,消息被刪除了怎么辦?
這。。。他媽都刪除了我有啥辦法啊。。。冷靜,再想想。。有了。
最初,我們發送的消息記錄是落庫保存了的,而轉發發送的數據也保存了,那么我們就可以通過這部分數據來找到丟失的那部分數據,再單獨跑個腳本重發就可以了。如果轉發的程序沒有落庫,那就和消費方的記錄去做對比,只是過程會更艱難一點。
說了這么多,那你說說RocketMQ實現原理吧?
RocketMQ由NameServer注冊中心集群、Producer生產者集群、Consumer消費者集群和若干Broker(RocketMQ進程)組成,它的架構原理是這樣的:
為什么RocketMQ不使用Zookeeper作為注冊中心呢?
我認為有以下幾個點是不使用zookeeper的原因:
那Broker是怎么保存數據的呢?
RocketMQ主要的存儲文件包括commitlog文件、consumequeue文件、indexfile文件。
Broker在收到消息之后,會把消息保存到commitlog的文件當中,而同時在分布式的存儲當中,每個broker都會保存一部分topic的數據,同時,每個topic對應的messagequeue下都會生成consumequeue文件用于保存commitlog的物理位置偏移量offset,indexfile中會保存key和offset的對應關系。
CommitLog文件保存于${Rocket_Home}/store/commitlog目錄中,從圖中我們可以明顯看出來文件名的偏移量,每個文件默認1G,寫滿后自動生成一個新的文件。
由于同一個topic的消息并不是連續的存儲在commitlog中,消費者如果直接從commitlog獲取消息效率非常低,所以通過consumequeue保存commitlog中消息的偏移量的物理地址,這樣消費者在消費的時候先從consumequeue中根據偏移量定位到具體的commitlog物理文件,然后根據一定的規則(offset和文件大小取模)在commitlog中快速定位。
Master和Slave之間是怎么同步數據的呢?
而消息在master和slave之間的同步是根據raft協議來進行的:
你知道RocketMQ為什么速度快嗎?
是因為使用了順序存儲、Page Cache和異步刷盤。
什么是事務、半事務消息?怎么實現的?
事務消息就是MQ提供的類似XA的分布式事務能力,通過事務消息可以達到分布式事務的最終一致性。
半事務消息就是MQ收到了生產者的消息,但是沒有收到二次確認,不能投遞的消息。
實現原理如下:
最終,如果MQ收到二次確認commit,就可以把消息投遞給消費者,反之如果是rollback,消息會保存下來并且在3天后被刪除。
關注公眾號:科技繆繆,獲取更多精彩技術文章和電子書
- END -
總結
以上是生活随笔為你收集整理的active mq topic消费后删除_《我想进大厂》之MQ夺命连环11问的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么判断自己适不适合读博士?
- 下一篇: 与「韦神」齐名,他35岁任教清华!18岁