通过损坏的网络发送JMS消息

通过损坏的网络发送JMS消息,jms,activemq,Jms,Activemq,我正在使用ActiveMQ执行一些简单的测试,以了解它在非稳定网络上的性能。第一个测试由一个生产者组成,该生产者将消息发送到远程队列。消息类型为ObjectMessage,其中包含可序列化的内容(对象列表) 有了良好的网络,一切都正常工作,但当我启动相同的测试来模拟包丢失、延迟和损坏时,我在尝试提取消息内容时,在使用消息时会出现以下错误: 2011-03-16 11:59:21791错误[com.my.MessageConsumer]无法从字节生成正文。原因:java.io.StreamCorr

我正在使用ActiveMQ执行一些简单的测试,以了解它在非稳定网络上的性能。第一个测试由一个生产者组成,该生产者将消息发送到远程队列。消息类型为ObjectMessage,其中包含可序列化的内容(对象列表)

有了良好的网络,一切都正常工作,但当我启动相同的测试来模拟包丢失、延迟和损坏时,我在尝试提取消息内容时,在使用消息时会出现以下错误:

2011-03-16 11:59:21791错误[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(); } } } 公共类myMessageConsumer实现MessageListener{ 消息(消息消息)上的公共无效{ 尝试 { if(ObjectMessage的消息实例){ ObjectMessage myMessage=(ObjectMessage)消息; List dtoList=(List)myMessage.getObject(); } }捕获(例外情况除外){ 例如printStackTrace(); } } }
如果需要确切的代码,我会在我度假回来的时候把它放进去,但它就是这样。

代理不会验证它处理的每一条消息的内容,这将是一个巨大的时间浪费,并大大降低消息发送的速度。客户端收到一条错误消息并抛出JMSException以指示消息内容已损坏,这应该足以让您的应用程序正确响应。

您的代码在哪里

如果该异常来自您的代码,那么您可能有一个bug。例如,在接收消息时遇到一些JMS错误,但却打乱了错误处理并试图处理结果。对于您描述的测试,您需要很好地关注客户机中的错误处理


我没有使用ActiveMQ的经验,但它会允许损坏的消息传递,这似乎非常令人惊讶。我并不希望JMS实现将ObjectMessage解包以进行检查。只是它应该提供发送内容的一个字节对一个字节的未损坏副本。或者,如果不能,则出错。

我认为代理不应该通过取消邮件的签名来进行任何验证。它只是应该将消息发送到目的地(消费者),而目的地就是解封消息的地方。我不是指解封消息,但至少进行了一些完整性检查?因此,在消息被消费之前,制作者无法知道消息是否正确发送?@jasalguero:消息确实正确发送,制作者确实从代理处得到了确认。然而,对代理上的任何消息进行验证/完整性检查并不是代理的工作。对于代理来说,它只是一个普通的序列化对象。这是我的想法,这就是为什么我对结果感到惊讶。我这里没有代码,但我发布了我记得的,这是一个非常简单的示例,只是获取消息并提取可序列化列表。