摘要:利用的高級特性特性是一種負載均衡的機制。在一個消息被分發到之前,首先檢查消息屬性。屬性為某個值的消息單個消息或消息集合在描述,和的對應關系,以及負載均衡策略時。同樣做到了保證消息的順序情況下,均衡消費的消費消息。
通常mq可以保證先到隊列的消息按照順序分發給消費者消費來保證順序,但是一個隊列有多個消費者消費的時候,那將失去這個保證,因為這些消息被多個線程并發的消費。但是有的時候消息按照順序處理是很重要的,那我們該如何來保證消息的順序呢,下面將從activemq和rocketmq來看看,它們是如何來保證消息的順序問題的?我們還可以有別的處理方案么?
Activemq處理方案
1、利用Activemq的高級特性:consumer之獨有消費者(exclusive consumer)
在ActiveMQ4.x中可以采用Exclusive Consumer,broker會從queue中,一次發送消息給一個消費者,這樣就避免了多個消費者并發消費的問題,從而保證順序,配置如下:
queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true"); consumer = session.createConsumer(queue);
當在接收信息的時候有一個或者多個備份接收消息者和一個獨占消息者的同時接收時候,無論兩者創建先后,在接收的時候,均為獨占消息者接收。
當在接收信息的時候,有多個獨占消費者的時候,只有一個獨占消費者可以接收到消息。
當有多個備份消息者和多個獨占消費者的時候,當所有的獨占消費者均close的時候,只有一個備份消費者接到到消息。
當主消費者掛了話,會立刻啟用故障切換轉移到下一臺消費者繼續消費
圖1
獨占消息就是在有多個消費者同時消費一個queue時,可以保證只有一個消費者可以消費消息,這樣雖然保證了消息的順序問題,不過也帶來了一個問題,就是這個queue的所有消息將只會在這一個主消費者上消費,其他消費者將閑置,達不到負載均衡分配,而實際業務我們可能更多的是這樣的場景,比如一個訂單會發出一組順序消息,我們只要求這一組消息是順序消費的,而訂單與訂單之間又是可以并行消費的,不需要順序,因為順序也沒有任何意義,有沒有辦法做到呢?答案是可以的,下面就來看看activemq的另一個高級特性之messageGroup。
2、利用Activemq的高級特性:messageGroups
Message Groups特性是一種負載均衡的機制。在一個消息被分發到consumer之前,broker首先檢查消息JMSXGroupID屬性。如果存在,那么broker會檢查是否有某個consumer擁有這個message group。如果沒有,那么broker會選擇一個consumer,并將它關聯到這個message group。此后,這個consumer會接收這個message group的所有消息,直到:
Consumer被關閉
Message group被關閉,通過發送一個消息,并設置這個消息的JMSXGroupSeq為-1
圖2
配置如下:
bytesMessage.setStringProperty("JMSXGroupID", "constact-20100000002"); bytesMessage.setIntProperty("JMSXGroupSeq", -1);
如上圖所示,同一個queue中,擁有相同JMSXGroupID的消息將發往同一個消費者,解決順序問題,不同分組的消息又能被其他消費者并行消費,解決負載均衡的問題,兩全其美啦!
問題討論,除了上述Activemq為我們提供的方案,我們是否不依賴這兩種特性,也能解決順序問題呢?
Rocketmq處理方案
那rocketmq又是如何保證消息順序消費的問題呢?
Rocketmq跟傳統的MQ有一點區別,這里有必要講一下topic的概念,Topic是RocketMQ中的一個重要概念,RocketMQ的各組件都是圍繞著Topic建立起對應關系的,在RocketMQ官方文檔和本文中, Topic在不同的語境下被賦予了兩種不同的語義:
1)消息的Topic屬性值:在描述Consumer的訂閱設置信息或消息的屬性時。
2)Topic屬性為某個值的消息(單個消息或消息集合):在描述Broker,Producer和Consumer的對應關系,Queue以及負載均衡策略時。
topic和queue的對應關系是一個topic擁有多個queue,當producer往broken發送消息時,消息會存儲在topic下的不同隊列中,而一個隊列只會被一個consumer消費,這樣消息戶被均衡負載到不同的隊列下,也就是會被多個消費者并行消費,順序就無法保證了。該怎么辦呢?答案是把需要順序消費的消息發送到同一臺broker server下的同一個隊列,而這些消息也只會被同一個消費者消費,這樣就可以保證嚴格的順序了,如下圖:
1、消息要有順序,首先得保證producer發送消息有順序,如上圖msg1,msg2,msg3發送到queue0是要有順序的,只要producer等待前面的消息發送成功,在發送后面的消息就完全可以保證了,
2、假設msg1發送給consumer1,消費沒有響應,該怎么辦呢?是繼續發送msg2還是重新發送msg1,一般為了保證消息一定被消費,肯定會選擇重發msg1到下一臺消費者consumer2。
3、消費端1沒有響應Server時有兩種情況,一種是msg1確實沒有到達(數據在網絡傳送中丟失),另外一種消費端已經消費msg2且已經發送響應消息,只是MQ Server端沒有收到。如果是第二種情況,重發msg1,就會造成msg1被重復消費。也就引入了消息重復問題,那就要冪等了。
Rocketmq同樣做到了保證消息的順序情況下,均衡消費的消費消息。
綜上,我看到,在分布式系統中,要想消息有順序的被消費,無論是Activemq還是Rocketmq都要想辦法讓有順序的消息被同一消費者消費,而不是并發的消費,在消費者消費成功后,接著才會消費下一個消息,這樣就可以保證了嚴格的順序。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69153.html
摘要:緊接著征用倍的機器來部署,每一批消費一個臨時的消息。這種做法相當于臨時將資源和資源擴大倍,以正常速度的倍來消費消息。解決方案這種情況下,實際上沒有什么消息擠壓,而是丟了大量的消息。 1.大量消息在mq里積壓了幾個小時了還沒解決 場景: 幾千萬條數據在MQ里積壓了七八個小時,從下午4點多,積壓到了晚上很晚,10點多,11點多。線上故障了,這個時候要不然就是修復consumer的問題,讓他恢復消...
摘要:一個對應一個,但是里面進行了多線程消費,這樣也會造成消息消費順序錯誤。保證消息的消費順序拆分多個,每個一個,就是多一些而已,確實是麻煩點這樣也會造成吞吐量下降,可以在消費者內部采用多線程的方式取消費。 1.為什么要保證順序 消息隊列中的若干消息如果是對同一個數據進行操作,這些操作具有前后的關系,必須要按前后的順序執行,否則就會造成數據異常。舉例: 比如通過mysql binlog進行兩個數據...
摘要:比如,服務數據庫的數據來源于服務的數據庫服務的數據有變更操作時,需要同步到服務中。第二種解決方案通過數據庫的進行同步。并且,我們還用這套架構進行緩存失效的同步。目前這套同步架構正常運行中,后續有遇到問題再繼續更新。在微服務拆分的架構中,各服務擁有自己的數據庫,所以常常會遇到服務之間數據通信的問題。比如,B服務數據庫的數據來源于A服務的數據庫;A服務的數據有變更操作時,需要同步到B服務中。第一...
摘要:消息生產者,負責發消息到。消息消費者,負責從上拉取消息進行消費,消費完進行。集群部署端完全消費正常后在進行手動確認。消息發送成功后,服務器返回確認消息給生產者。根據本地事務執行的結果向發送提交或回滾消息。 RabbitMQerlang開發,對消息堆積的支持并不好,當大量消息積壓的時候,會導致RabbitMQ的性能急劇下降。...
摘要:將消息持久化成功之后,向發送方確認消息已經發送成功,此時消息為半消息。發送方收到消息回查后,需要檢查對應消息的本地事務執行的最終結果。發送方根據檢查得到的本地事務的最終狀態再次提交二次確認,仍按照步驟對半消息進行操作。1.應用場景 解耦 異步 流量消峰 日志記錄 2.重復消息的解決方案 消費端處理消息的業務邏輯保持冪等性 保證每條消息都有唯一編號且保證消息處理成功與去重表的日志同時出現...
閱讀 3161·2023-04-25 19:09
閱讀 3875·2021-10-22 09:54
閱讀 1743·2021-09-29 09:35
閱讀 2904·2021-09-08 09:45
閱讀 2231·2021-09-06 15:00
閱讀 2766·2019-08-29 15:32
閱讀 1029·2019-08-28 18:30
閱讀 370·2019-08-26 13:43