2011-03-16 95 views
0

我正在使用ActiveMQ執行一些簡單的測試,以瞭解它如何在非穩定網絡上執行。第一個測試包括一個將消息發送到遠程隊列的生產者。該消息的類型爲ObjectMessage,其中包含可序列化的內容(對象列表)。通過損壞的網絡發送JMS消息

有了一個良好的網絡一切正常,但是當我啓動相同的測試using netem模擬包損失,延遲和腐敗我得到消耗的消息時試圖提取消息的內容時出現以下錯誤:

2011-03-16 11:59:21,791錯誤[com.my.MessageConsumer]無法從字節構建主體。原因:java.io.StreamCorruptedException:無效句柄值:017E0007 javax.jms.JMSException:無法從字節構建主體。原因:java.io.StreamCorruptedException:無效的句柄值:017E0007

所以它看起來像在發送到遠程隊列已損壞的消息,但無論如何存儲,並且僅消耗當消費者看到該消息已損壞。

在此之後,我將使用本地隊列和網絡連接器將消息轉發到遠程隊列,並且我希望它可以解決問題,但是我驚訝於生產者和生產者之間沒有任何驗證目的地(至少是一個校驗和或類似的東西),保證正確的交付,我做錯了什麼或者是正常的行爲?

我沒有代碼在這裏,現在,但它是超級簡單,只是一個MessageListener:

 

public class myMessageConsumer implements MessageListener{ 

    public void onMessage(Message message){ 

     try 
     { 

      if (message instanceof ObjectMessage){ 
        ObjectMessage myMessage = (ObjectMessage) message; 
        List dtoList = (List) myMessage.getObject(); 
      } 
     } catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
    } 
} 

如果需要確切的代碼我把它當我回去的假期,但完全如此。

+0

嗯,我不認爲經紀人應該通過解組消息來做任何驗證。它只是應該發送消息到目的地(消費者),這就是它被解組的地方。 – anubhava 2011-03-16 15:36:48

+0

我並不是指解組消息,但至少有一些完整性檢查? – jasalguero 2011-03-17 07:41:53

回答

0

代理不會驗證它處理的每封郵件的內容,這會浪費大量時間並顯着減慢郵件的發送速度。客戶端收到一條錯誤消息,並拋出一個JMSException來指示消息內容已損壞,這應該足以讓您的應用正確響應。

+0

因此,生產者無法知道消息是否被正確發送,直到被消費? – jasalguero 2011-03-17 07:42:30

+0

@jasalguero:消息確實發送正確,Producer確實從代理獲得了ACK。然而,經紀人本身的信息驗證/完整性檢查並不是經紀人的工作。對於代理來說,它只是一個普通的序列化對象。 – anubhava 2011-03-17 12:21:36

0

你的代碼在哪裏?

如果這個異常來自您的代碼,似乎有可能您有一個錯誤。例如,獲取一些JMS錯誤接收消息,但搞亂了錯誤處理並試圖處理結果。對於您所描述的測試,您需要將重點放在客戶端的錯誤處理上。

我沒有與ActiveMQ的經驗,但它似乎讓人非常驚訝,它會允許損壞的消息傳遞。並不是說我想讓JMS實現解開ObjectMessage來檢查。只是它應該爲發送的內容提供逐字節的未損壞副本。或者如果不行,就會報錯。

+0

那是我的想法,這就是爲什麼結果感到驚訝。我沒有這裏的代碼,但我發佈了我記得的東西,這是一個非常簡單的例子,只是獲取消息並提取可序列化的列表。 – jasalguero 2011-03-18 07:41:44