主要思路有兩種:一、單線程消費來保證消息的順序性;二、對消息進行編號,消費者處理時根據編號判斷順序。 面試
一、rabbitMq
問題分析:
如圖,data1 和 data2 是有順序的,必須 data1 先執行,data2 後執行;這兩個數據被不一樣的消費者消費到了,可能 data2 先執行,data1 後執行,這樣原來的順序就錯亂了。數據庫
解決方案:
如圖,在 MQ 裏面建立多個 queue,同一規則的數據(對惟一標識進行 hash),有順序的放入 MQ 的 queue 裏面,消費者只取一個 queue 裏面獲取數據消費,這樣執行的順序是有序的。或者仍是隻有一個 queue 可是對應一個消費者,而後這個消費者內部用內存隊列作排隊,而後分發給底層不一樣的 worker 來處理。多線程
二、kafka
問題分析:
如圖,在 kafka 中,你對數據指定某個 key,那麼這些數據會到同一個 partition 裏面,在 partition 裏面這些數據是有順序的。從這裏看沒啥問題,插入到數據庫的數據都是有序的。負載均衡
可是,咱們在消費端可能會使用多線程來處理,由於單線程的處理速度慢,爲了加快處理時間和吞吐量,會使用 thread 來處理。在消費端加入線程以後,就會出現順序不一致的狀況。
如圖,就是使用了多線程以後,數據順序不一致狀況。spa
在使用了多線程以後,如何來解決數據順序問題?
如圖,在消費端使用內存隊列,隊列裏的數據使用 hash 進行分發,每一個線程對應一個隊列,這樣能夠保證數據的順序。線程
三、rocketMq隊列
如圖,生產者中把 orderId 進行取模,把相同模的數據放到 messagequeue 裏面,消費者消費同一個 messagequeue,只要消費者這邊有序消費,那麼能夠保證數據被順序消費。內存
四、activeMq
如圖,activeMq 裏面有 messageGroups 屬性,能夠指定 JMSXGroupID,消費者會消費指定的 JMSXGroupID。即保證了順序性,又解決負載均衡的問題。get