1. 程式人生 > >ActiveMQ 的獨佔消費模式

ActiveMQ 的獨佔消費模式

本文主要介紹一下ActiveMQ訊息獨佔模式

 

1、訊息獨佔模式(Exclusive Consumer)

 

Queue中的訊息是按照順序被分發到consumers的。然而,當你有多個consumers同時從相同的queue中提取訊息時,你將失去這個保證。因為這些訊息是被多個執行緒併發的處理。有的時候,保證訊息按照順序處理是很重要的。例如,你可能不希望在插入訂單操作結束之前執行更新這個訂單的操作。 ActiveMQ從4.x版本起開始支援Exclusive Consumer (或者說Exclusive Queues)。 Broker會從多個consumers中挑選一個consumer來處理queue中所有的訊息,從而保證了訊息的有序處理。如果這個consumer失效,那麼broker會自動切換到其它的consumer。 可以通過Destination Options 來建立一個Exclusive Consumer,如下:
Java程式碼
1. queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true");
2. consumer = session.createConsumer(queue);
順便說一下,可以給consumer設定優先順序,以便針對網路情況(如network hops)進行優化,如下:
Java程式碼
1. queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true &consumer.priority=10");

 

2、支援負載均衡的訊息的順序消費思路

 

         (1)以一個訂單產生為例,使用者進行下單時會產生訂單,訂單生成成功,則需要減庫存等一系列操作。類似上述場景都需要訊息順序高效的執行。

         (2)如果使用獨佔消費者模式可以解決順序消費的問題,但是如果當訂單量非常龐大時,每次訊息中間上的資料只能交給一個消費者去處理,這樣效率就會很低。

         (3)解決這個問題的思路是,可以在訊息中介軟體(Broker)與Consumer之間新增一個叢集(cluster,代理伺服器角色)該叢集主要目的用於將broker上的訊息進行排隊,該cluster的大致設計是可以建立一個ConcurrentHashMap的佇列,佇列的key可以使用String型別的訂單ID,value可以使用一個ConcurrentLinkedQueue的佇列。這樣每次通過一些業務邏輯處理,將代理伺服器的訊息推送給每一個Consumer(這裡的Consumer也可以是一個叢集),對於每一個Consumer而言,在處理一個訂單資料時,每處理完一個訂單裡的一條訊息時都要將訊息的返回結果通知代理伺服器,代理伺服器得知訂單中訊息的處理情況後,就可以將同一個訂單中的第二條資料推送給另外一個Consumer,第二個Consumer的處理邏輯與第一個的相同。這樣處理方式可以保證每一個訂單的資料訊息都是順序執行的。在這個期間對於第一個Cosumer而言,還可以併發處理第二個訂單中的訊息。對於整個系統而言,順序處理訊息的時間可能沒有特別大的變化,但是對於整個系統而言,系統的吞吐量變大了。