使用代理重新传递插件时,ActiveMQ有时会丢失消息属性

时间:2014-01-22 15:49:23

标签: activemq spring-jms

我们将ActiveMQ 5.8.0与Spring JMS 3.2.3.RELEASE结合使用。应用程序使用Spring DefaultMessageListenerContainer侦听队列,并使用Spring ActiveMQTextMessage将对象存储在MappingJackson2MessageConverter中。

我们还使用ActiveMQ代理重新传递插件,该插件在activemq.xml中配置。消息保存在Oracle数据库中,也在activemq.xml

中配置

现在我们遇到以下问题:在重新传递的大约60%的消息中,javaClass在消息上设置的MappingJackson2MessageConverter属性丢失了。这会导致以下堆栈跟踪:

org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [javaClass]
            at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:360)
            at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:176)

在检查数据库中的持久消息时,我们发现javaClass属性确实丢失了。但是redeliveryDelay设置的AMQ_SCHEDULED_DELAYRedeliveryPlugin属性存在。

这可能是由ActiveMQ中的错误引起的吗?我看到RedeliveryPlugin.scheduleRedelivery()marshalledProperties设置为null,这应该是正确的行为,以确保所有属性都在Message.beforeMarshall()中序列化。但是如果属性是懒惰创建的,并且还没有调用创建它们的方法(即getProperty()或某些此类),那么将marshalledProperties清除掉在重新传递插件之前设置的属性。 / p>

以下单元测试证明,使用org.apache.activemq.command.Message

的当前实现可以实现此方案
@Test
public void testGetPropertyAfterUnmarshallAndNullMarshalledProperties() throws IOException {
    ActiveMQTextMessage msg = new ActiveMQTextMessage();
    msg.setProperty(TYPEID_PROPERTY, TEST_CLASS);

    OpenWireFormat wireFormat = new OpenWireFormat(CommandTypes.PROTOCOL_VERSION);
    msg.beforeMarshall(wireFormat);

    ByteSequence byteSequence = wireFormat.marshal(msg);

    ActiveMQTextMessage unmarshalled = (ActiveMQTextMessage) wireFormat.unmarshal(byteSequence);

    // simulate RedeliveryPlugin behaviour
    unmarshalled.setMarshalledProperties(null);

    assertNull(unmarshalled.getProperty(TYPEID_PROPERTY));
}

使用代理重新传递插件时有没有人看到过这种行为?我们开始使用代理插件,因为我们遇到了客户端重新传递机制的问题,所以回到那个不是一个选项。

0 个答案:

没有答案