Apache Camel:收到未知correlationID的回复

时间:2014-01-16 17:08:51

标签: java concurrency activemq apache-camel

其他两个软件组件之间有middleware个。在middleware我通过Apache ActiveMQ发送Apache Camel邮件。

这是它的工作原理:

  1. 1stComponent使用middleware3rdComponent
  2. 发送消息
  3. 3rdComponent回复该邮件并将其发回1st(使用middleware)。

               1stComponent <<=>> Middleware <<=>> 3rdComponent
    
  4. 问题:

    我在中间件中使用ConcurrentConsumers

    在顺序发送大量消息的过程中,突然middleware停止所有进程! 没有例外或消息! 例如,500条消息中的前100条被处理,剩余部分作为待处理消息保留在队列中。

    有时会在过程中间记录此警告:

    [WARN ] TemporaryQueueReplyManager(Camel (camel-1) thread #11 - TemporaryQueueReplyManager[Q.MyQ]):91 - Reply received for unknown correlationID [c551c7aa061f501c]. The message will be ignored: ActiveMQMapMessage {commandId = 2161, responseRequired = true, messageId = ID:xxxxxxx, originalDestination = null, originalTransactionId = null, producerId = ID:xxxxxxx, destination = temp-queue://ID:localhost.localdomain-40961-1389890357282-3:1:1, transactionId = null, expiration = 0, timestamp = 1389890272360, arrival = 0, brokerInTime = 1389890272360, brokerOutTime = 1389890272360, correlationId = c551c7aa061f501c, replyTo = temp-queue://ID:localhost.localdomain-40961-1389890357282-3:1:1, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = org.apache.activemq.util.ByteSequence@19e19da, dataStructure = null, redeliveryCounter = 0, size = 0, properties = {breadcrumbId=ID:xxxxxxxxxxxxxx, Title=300, CamelJmsDeliveryMode=1}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {} }
    

    这是middlewares代码:

    private static class MyRouteBuilder extends RouteBuilder {
        @Override
        public void configure() throws Exception {
            from("activemq:queue:Q.Middleware?concurrentConsumers=1&maxConcurrentConsumers=10")
            .threads(1, 100)
                .process(new Processor() {
                    public void process(Exchange exchange) {
                        //some code
                    }
                })
            .inOut("activemq2:queue:Q.3RD")
            ;
        }
    }
    

    3rdComponent

    private static class MyRouteBuilder extends RouteBuilder {
        @Override
        public void configure() {
            from("activemq:queue:Q.3RD")
            .threads(1, 100)
            .process(new Processor() {
                public void process(Exchange exchange) {
                    //some code
                }
            })
            ;
        }
    }
    

4 个答案:

答案 0 :(得分:1)

当您使用请求/响应范例时(由于您的路由中有InOut,您正在使用它),生产者希望在发送下一个消息之前获得对它发送的每条消息的响应。如果两个生产者生成的消息将来到同一个响应目的地并且他们正在使用相同的选择器观察该目的地,那么一个消息是一个竞争条件,无论消息是来到生产者期望它还是另一个消息,如果它转到另一个,您将获得您在生产者中看到的意外回复的消息,以及一条消息,指示在发送原始消息的生产者中等待响应的超时。

这就是为什么你的“回答”(实际上没有回答你的问题,只描述如何可靠地重现你的问题)能够通过启动多个并行路由来重现问题,这些路由将InOut消息发送到同一目的地。

要解决此问题,您需要确保您的制作人只能通过每个制作人的单独回复目的地,通过每个制作人的唯一选择器或通过减少制作人数来获得他们自己的消息。

答案 1 :(得分:0)

@Amin Ralf正确地在他的回复中添加了更多内容---这个过程可能有两个原因停止 1 - TTL已过期 2 - 客户端和服务器之间的时间不同步。

如果您的问题与1相关,则设置标题 - “JMSExpiration”

如果您的问题与2 - (从另一个stackoverflow帖子粘贴的副本)

相关

然后客户端 - 代理之间的时钟需要同步,以使到期工作正常。如果时钟不同步,则当在代理上接收到消息时,从客户端设置的到期时间可能已经过期。或者客户时间早于经纪人,因此到期时间超过10秒。

要通过重新调整时间来解决此问题,只需基于经纪人。见http://activemq.apache.org/timestampplugin.html

答案 2 :(得分:0)

<强>更新

My previous answer工作正常,但不是完整的解决方案。

错误是生成非唯一 CorrelationIDs(随机字符串生成器中的错误)简单!!! :|

答案 3 :(得分:-1)

没人知道为什么!但我找到了这个解决方案:

可以使用以下多条路线来模拟此功能:

...
        // ----<1st Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<2nd Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<3rd Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<4th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<5th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<6th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<7th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<8th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<9th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
        // ----<10th Route>----
        from("activemq:queue:Q.Middleware").threads(2, 20).inOut("activemq2:queue:Q.3RD");
...

它工作正常,但管理它的消费者数量(路由)是不合适的!你应该复制&amp;粘贴路线!