面試連環炮
- 你用過消息隊列麼?
- 說說你們項目裏是怎麼用消息隊列的?
- 我們有一個訂單系統,訂單系統會每次下一個新訂單的時候,就會發送一條消息到ActiveMQ裏面去,後臺有一個庫存系統,負責獲取消息,然後更新庫存。
- 爲什麼使用消息隊列?
- 你的訂單系統不發送消息到MQ,而是直接調用庫存系統的一個接口,然後直接調用成功了,庫存也更新了,那就不需要使用消息隊列了呀
- 使用消息隊列的主要作用是:異步、解耦、削峯
- 消息隊列都有什麼優缺點?
- Kafka、activeMQ、RibbitMQ、RocketMQ都有什麼優缺點?
- 如何保證消息隊列的高可用?
- 如何保證消息不被重複消費?如何保證消息消費時的冪等性?
- 如何保證消息的可靠性傳輸,要是消息丟失了怎麼辦?
- 如何保證消息的順序性?
- 如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以後該怎麼處理?有幾百萬消息持續積壓幾小時,說說怎麼解決?
- 如果讓你寫一個消息隊列,該如何進行架構設計,說一下你的思路?
面試題
如何保證消息的順序性?
場景
以前做過一個MySQL binlog同步系統,壓力還是非常大的,日同步數據要達到上億。常見一點的在於 大數據項目中,就需要同步一個mysql庫過來,然後對公司業務的系統做各種的複雜操作。
在mysql裏增刪改一條數據,對應出來的增刪改3條binlog,接着這三條binlog發送到MQ裏面,到消費出來依次執行,這個時候起碼得保證能夠順序執行,不然本來是:增加、修改、刪除,然後被換成了:刪除、修改、增加,不全錯了呢。
本來這個數據同步過來,應該是最後刪除的,結果因爲順序搞錯了,最後這個數據被保留了下來,數據同步就出錯
- RabbitMQ:一個queue,多個consumer,這不明顯亂了
- Kafka:一個topic,一個partition,一個consumer,內部多線程,就會亂套
在消息隊列中,一個queue中的數據,一次只會被一個消費者消費掉
但因爲不同消費者的執行速度不一致,在存入數據庫後,造成順序不一致的問題
RabbitMQ保證消息順序性
RabbitMQ:拆分多個queue,每個queue一個consumer,就是多一些queue而已,確實是麻煩,或者就是一個queue,但是對應一個consumer,然後這個consumer內部用內存隊列做排隊,然後分發給底層不同的worker來處理。
下圖爲:一個consumer 對應 一個 queue,這樣就保證了消息消費的順序性。
Kafka保證消息消息順序性
一個topic,一個partition,一個consumer,內部單線程消費,寫N個內存,然後N個線程分別消費一個內存queu即可。注意,kafka中,寫入一個partition中的數據,一定是有順序的,
但是在一個消費者的內部,假設有多個線程併發的進行數據的消費,那麼這個消息又會亂掉
這樣時候,我們需要引入內存隊列,然後我們通過消息的key,然後我們通過hash算法,進行hash分發,將相同訂單key的散列到我們的同一個內存隊列中,然後每一個線程從這個Queue中拉數據,同一個內存Queue也是有順序的。