当前位置: 首页 > 知识库问答 >
问题:

Camel和JMS以正确的顺序从高级队列中消费消息

蔺劲
2023-03-14

我将Apache Camel与Oracle高级队列和JMS结合使用时遇到了问题。

它是关于一个分发消息的应用程序。消息在Camel的帮助下被接收并在Oracle高级队列中排队。然后它们被Camel使用并转发到目标系统。对于消息传递失败的情况,在高级队列中定义了重试计数,以便重复消息传递。

如果Camel现在将消息退出队列并将其发送到不可用的目标系统,则会引发HttpOperationFailedException或NoSuchEndpointException。这些被捕获并执行回滚。

此时,预期消息传递将按照“重试计数”中定义的频率重试,然后移动到异常队列。然而,正在发生的是队列中的下一条消息被发送。

由于消息的内容部分相互依赖,因此必须按顺序处理它们。

我认为 JMS 库的使用存在错误配置,但我不确定并且没有发现任何可以影响此行为的内容。

使用的 JMS 库是 Oracle AqApi v 11.2.0.3。

以下是骆驼路线的代码:

from("jms-camel-component:myComponent.AQ?jmsMessageType=Text").routeId("deliveryToTarget")
        .transacted()                
        .setExchangePattern(ExchangePattern.InOut)                        
        .setHeader(Exchange.HTTP_QUERY, constant("throwExceptionOnFailure=false"))
        .setHeader(Exchange.CONTENT_TYPE, constant("application/xml; charset=UTF-8"))
        .doTry()
            .recipientList(header("endpointTarget"))
            .endDoTry()
            .process(ResponseProzessor.getInstance())
            .log("Message was delivererd.")
        .doCatch(HttpOperationFailedException.class, NoSuchEndpointException.class)    
            .process(ResponseProzessor.getInstance())
            .log("Error occured.")
            .rollback()
        .end();

下面是 JmsComponent 配置:

JmsComponent jmsComponent = new JmsComponent(scc);
jmsComponent.setConnectionFactory(connectionFactory);
jmsComponent.setTransactionManager(tm);
jmsComponent.setMaxConcurrentConsumers(1);            
jmsComponent.setMaxMessagesPerTask(1);                  
jmsComponent.setIncludeSentJMSMessageID(true);

提前感谢您的帮助!

更新

我想,我已经找到了所描述行为的原因。在高级队列上配置了延迟。只要延迟持续,队列中的下一条消息就会取消排队。消息不是随机取消排队的,而是根据优先级取消排队的。

我真的认为这是必须在消费者身上配置的东西。是否有任何技巧可以将 camel-jms-组件配置为使用队列中的第一条消息,只要它没有提交或移动到异常队列?我没有找到直接在骆驼上配置它的选项......

共有1个答案

陆正德
2023-03-14

我不是Oracle AQ专家,但据我所知,这是队列上的设置,而不是客户端上的设置。

sort_list 参数确定消息取消排队的顺序。创建队列表后,无法更改邮件排序顺序

来自:http://docs . Oracle . com/CD/b 19306 _ 01/server . 102/b 14257/AQ _ admin . htm

你很可能有ENQ_TIME或COMMIT_TIME——这可能已经满足了你的需求。

当然,你的消费者必须是唯一的。

 类似资料:
  • 我有以下场景:有3个rabbitmq队列,生产者根据消息的优先级将消息推送到这些队列。(myqueue_high,myqueue_medium,myqueue_low)我希望有一个可以按顺序或优先级从这些队列中提取的单一使用者,即只要消息在那里,它就一直从高队列中提取。它是从介质中拉出来的。如果medium也是空的,它从Low拉出。 我如何实现这一点?我需要编写自定义组件吗?

  • 下面是我们设置的简化/示意图拓扑 每个节点(服务器)都是一个独立的(无集群)jboss应用服务器(Jboss-as7),包括消息传递服务器。 消息传递服务器部署许多JMS队列。 每个任务服务器为每个队列部署一个MDB,每个队列有许多使用者。 所有消息生产者使用相同的入站适配器,所有消息使用者使用相同的出站适配器。事实上,所有前端节点都是完全相同的(与所有服务器节点相同,配置相同,部署的工件相同)。

  • 我们的环境由3个jboss服务器组成(门户、jms、协调)。 协调服务器托管骆驼路由,该路由具有消耗自队列(SLAQueue)的路由 JMS服务器托管了我们的所有队列 最近,我们发现了一个错误,即托管在JMS服务器上的TaskQueue中的一些消息没有传递到门户服务器上的MDB。由于某些原因,它们被卡住了,当我们重新启动JMS服务器时,卡住的消息被传递 为了进行调查,我们在“org.apache.

  • 主要内容:1 start启动服务定时锁定消息队列,1.2 lockAll锁定所有消息队列,2 submitConsumeRequest提交消费请求,3 ConsumeRequest执行消费任务,3.1 tryLockLaterAndReconsume尝试延迟加锁并重新消费,3.2 takeMessages拉取消息,4 processConsumeResult处理消费结果,4.1 commit提交消息,4.2 checkReconsumeTimes检查重试次数,,,基于RocketMQ relea

  • 我正在研究一个示例,其中JMS队列托管在JBoss EAP 6实例上(一个用于请求,另一个用于响应)。我还有一个在Weblogic托管服务器上运行的应用程序。 我想设置一种机制,允许运行在Weblogic上的应用程序能够使用添加到JBoss上的请求队列上的消息。此外,应用程序应该能够将消息发布到请求队列(也托管在JBoss上) 我在Oracle文档中读到了关于外国JNDI提供程序的信息,我找到的大

  • 我有一个由第三方发布的JMS队列。我想在不同的机器上设置多个使用者,只有一台特定机器的使用者确认该队列上的消息。简而言之,如果特定机器的使用者没有接收到消息,那么该消息不应从队列中删除。这是可以实现的吗?