2014-03-27 178 views
0

我正在駱駝的一個機制,將選擇一個標誌,可以是true或false的消息端點。這是一種限制機制,在我的上行信道被淹沒的情況下,將消息重新路由到批量接收端點(發送到HDFS)。動態路由在駱駝

最終,我的路線是這樣的:

from("queue:myqueue").bean("messageParser") 
    .dynamicRoute(bean(ThrottleHelper.class, 'buildEndpoint')); 

from('direct:regular').to('hbase'); 

from('direct:throttle').to('hdfs'); 

我ThrottleHelper類的buildEndpoint方法是這樣的:

public static String buildEndpoint() { 
    synchronized(shouldThrottle) { 
     if(shouldThrottle) 
     return "direct:throttle"; 
     else 
     return "direct:regular" 
    } 
} 

目前,我對所謂的checkStatus()類的方法;其中設置的應該是Tottle(一個靜態變量)。 checkStatus()每分鐘在一個Camel石英計時器上運行。

我注意到了一些奇怪的行爲,我想我可能會濫用這種模式。通過對Camel實現該模式的進一步搜索,看起來buildEndpoint()將在消息遍歷每個返回的端點之後調用。這是真的?或者,我是否可以預期在「direct:throttle」或「direct:regular」之後路徑會終止?

從我在網上收集的信息看,我的方法應該看起來像這樣嗎?

public static String buildEndpoint(Message message) { 
    if(message.getHeader('throttled') != null) 
     return null; 
    else 
     message.setHeader('throttled', true); 

    synchronized(shouldThrottle) { 
     if(shouldThrottle) 
     return "direct:throttle"; 
     else 
     return "direct:regular" 
    } 
} 

謝謝!

+0

沒關係。我用單元測試驗證了這種行爲。我列出的第二種方法(測試以查看方法是否已被調用)有效。 我的下一個問題 - 爲什麼我會使用dynamicRouter,而不是讓我的ThrottleHelper使用「shouldThrottle」屬性來豐富每個消息的頭並使用基於該頭部屬性的基於內容的路由? –

回答

0

official documentation看起來,是的,你的第二個構造更接近正確的用法。基本上,動態路由器可用於通過多個端點路由消息,而不僅僅是立即終止的單個端點。要告訴動態路由器停止將您的消息路由到另一個端點,您的bean必須返回null(如您在最終代碼段中所寫),以表明此消息的路由已完成。

+0

這裏的想法是試圖擺脫我的郵件存儲額外的屬性。這也是爲了避免必須迭代過濾器/選擇來確定消息應該穿過哪個端點。然而,它確實似乎比它的價值更麻煩,特別是如果我仍然需要在消息上存儲狀態。我最好在這裏使用choice()構造。 –

+0

不夠公平,但我認爲你的基於內容的路由思想實際上是這種情況的最佳方法。使用附加屬性豐富您的消息是一個非常輕量級的選項,它的設計基本上可以幫助您確切的使用情況。也可以使用手頭上的工具,以更好地滿足您的需求。 – ProgrammerDan

+0

同意。感謝您的答覆! –

0

正如ProgrammerDan指出的那樣,動態路由器用於通過多個端點路由消息,因此需要顯式返回null以指示路由的結束。

如果您只想使用表達式或bean方法選擇一個端點,最好使用動態收件人列表(cfr。http://camel.apache.org/recipient-list.html)。如果您在路由生成器中使用.recipientList()而不是.dynamicRoute(),則您的第一個buildEndpoint方法實現將工作得很好。