2010-06-03 78 views
0

我有一個情況,我有一個activemq代理與2個隊列,Q1和Q2。我有兩個使用activemessaging的基於ruby的消費者。我們稱他們爲C1和C2。兩個消費者都訂閱每個隊列。訂閱每個隊列時,我將activemq.prefetchSize設置爲1。我也設置了ack =客戶端。activemeqaging與跺腳和activemq.prefetchSize = 1

考慮事件的序列如下:

1)觸發一個長時間運行的工作被髮布到隊列Q1的消息。稱這個M1。

2)M1發送給消費者C1,開始長時間的操作。

3)兩條觸發短作業的消息被髮布到隊列Q2。稱這些M2和M3。

4)M2被派遣到C2快速運行短期工作。

5)即使C1仍在運行M1,M3仍被分派到C1。它能夠分派到C1,因爲在隊列訂閱上設置了prefetchSize = 1,而不是在連接上。所以Q1消息已經被分派的事實並不會阻止一個Q2消息被分派。

由於主動消費者是單線程的,最終結果是M3坐在C1上等待很長時間直到C1完成處理M1。所以,儘管事實上消費者C2處於空閒狀態(因爲它很快完成了消息M2),所以M3不被處理很長一段時間。

從本質上講,無論什麼時候運行一個長的Q1作業,然後創建了一大堆短的Q2作業,恰好有一個短的Q2作業卡住了等待第一季度作業完成的消費者。

有沒有辦法在連接級別而不是在訂閱級別設置prefetchSize?我真的不希望在處理M1時向C1發送任何消息。另一種選擇是我可以創建一個專門處理Q1的消費者,然後讓其他消費者致力於處理Q2。但是,由於Q1消息不多,我寧願不這樣做 - Q1的專門消費者會在一天的大部分時間內閒置以佔用內存。

回答

2

根據ActiveMQ文檔的擴展腳本頭(http://activemq.apache.org/stomp.html),activemq.prefetchSize僅在SUBSCRIBE消息中可用,而不是CONNECT。下面是相關信息:

動詞:SUBSCRIBE

頭:activemq.prefetchSize

類型:int

描述:指定將 被分派的最大數目 未決消息的給客戶。一旦達到最大值 ,將不會再發送更多消息 ,直到客戶端 確認消息。設置爲1爲 消息處理 消息可能很慢,消息的消息的公平分配 。

我對此的閱讀和體驗是,由於M1沒有被確認(b/c你有客戶端確認打開),所以這個M1應該是prefetchSize = 1設置允許的1條消息訂閱。我很驚訝地聽說它不起作用,但也許我需要進行更詳細的測試。您的設置應該適合您所需的行爲。

我聽說過其他人關於activemq dispatch的片狀,所以有可能這是你使用的版本的錯誤。

我的一個建議是嗅探網絡流量以查看M1是否由於某種原因得到了迴應,或者將一些置入語句放入ruby stomp gem中以觀察通信(這是我通常最終在調試跺腳問題時做)。

如果我有機會嘗試一下,我會用我自己的結果更新我的評論。

一個建議:很可能會發送多個長處理消息,並且如果長處理消息的數量超過了您的處理數量,那麼您將在此修復中處理快速處理消息。

我傾向於至少有一個專門的進程,只是做快速的工作,或者換個說法,專用一組只能做更長時間工作的進程。讓所有的輪詢器消費者進程聽取多空均可能導致次優結果,而不管分派如何。進程組是配置一個消費者聽目的地的一個子集的方式:http://code.google.com/p/activemessaging/wiki/Configuration

processor_group名, * list_of_processors

A processor group is a way to run the poller to only execute a subset of 

處理器在輪詢組通過的 名稱命令行 參數。

You specify the name of the processor as its underscored lowercase 

版本。所以,如果你有一個 FooBarProcessor和BarFooProcessor在 處理器組,它看起來像 這樣:

ActiveMessaging::Gateway.define do |s| 
     ... 
     s.processor_group :my_group, :foo_bar_processor, :bar_foo_processor 
    end 

The processor group is passed into the poller like the following: 

    ./script/poller start -- process-group=my_group 
+0

感謝您的回覆。我們使用處理器組來區分高優先級和低優先級作業。高優先級的工作是由我們的用戶界面啓動的,低優先級的工作由cron啓動。我們可以在這裏使用一個處理器組,但是長時間運行的工作實際上每天只能啓動一次。我們可以從activemq中完全刪除它。對於長期的工作,我們主要是使用activemq進行容錯,因爲我們在多個服務器上擁有消費者。 – 2010-06-03 23:19:18

0

我不知道,如果ActiveMessaging支持這一點,但你可以取消你的其他消費者當長處理消息到達,然後在處理後重新訂閱它們。

它應該給你想要的效果。

+0

不支持主動消息。 – 2012-02-28 20:30:38