【问题标题】:Sending JMS message over corrupted network通过损坏的网络发送 JMS 消息
【发布时间】:2011-03-18 15:40:11
【问题描述】:

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

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

2011-03-16 11:59:21,791 错误 [com.my.MessageConsumer] 无法从字节构建正文。原因:java.io.StreamCorruptedException:无效句柄值:017E0007 javax.jms.JMSException:无法从字节构建正文。原因:java.io.StreamCorruptedException:无效句柄值:017E0007

因此,似乎消息在发送到远程队列时已损坏,但无论如何都已存储,只有在消费时,消费者才会看到消息已损坏。

之后我将使用本地队列和网络连接器将消息转发到远程队列,我希望它能解决问题,但令我惊讶的是生产者和生产者之间没有任何形式的验证保证正确交付的目的地(至少是校验和或类似的东西),我做错了什么还是正常行为?

我这里现在没有代码,但是超级简单,就是一个 MessageListener:

公共类 myMessageConsumer 实现 MessageListener{ public void onMessage(消息消息){ 尝试 { 如果(消息实例对象消息){ ObjectMessage myMessage = (ObjectMessage) 消息; 列表 dtoList = (List) myMessage.getObject(); } } 捕捉(异常前){ ex.printStackTrace(); } } }

如果需要确切的代码,我会在假期回来时提供,但就是这样。

【问题讨论】:

  • 好吧,我认为代理不应该通过解组您的消息来进行任何验证。它只是应该将消息发送到目的地(消费者),这就是它被解组的地方。
  • 我的意思不是解组消息,但至少要进行一些完整性检查?

标签: jms activemq


【解决方案1】:

代理不会验证它处理的每条消息的内容,这将极大地浪费时间并显着减慢消息发送速度。客户端收到错误消息并抛出 JMSException 以指示消息内容已损坏,这足以让您的应用正确响应。

【讨论】:

  • 所以生产者没有办法知道消息是否正确发送直到被消费?
  • @jasalguero:消息确实已正确发送,生产者确实从代理那里收到了 ACK。但是,对代理本身的任何消息进行验证/完整性检查并不是代理的工作。对于代理来说,它只是一个普通的序列化对象。
【解决方案2】:

你的代码在哪里?

如果该异常来自您的代码,那么您可能遇到了错误。例如,接收到消息时出现一些 JMS 错误,但会弄乱错误处理并尝试处理结果。对于您描述的测试,您需要重点关注客户端的错误处理。

我没有使用 ActiveMQ 的经验,但它允许损坏的消息传递似乎非常令人惊讶。并不是说我希望 JMS 实现解包 ObjectMessage 以进行检查。只是它应该提供已发送内容的逐字节未损坏副本。否则就报错。

【讨论】:

  • 这是我的想法,这就是为什么对结果感到惊讶。我这里没有代码,但我发布了我记得的内容,这是一个非常简单的示例,只是获取消息并提取可序列化列表。
猜你喜欢
  • 2017-09-26
  • 2019-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
相关资源
最近更新 更多