Использование сообщения в правильном порядке из расширенной очереди Camel и JMS
У меня проблема с использованием Apache Camel в сочетании с Oracle Advanced Queues и JMS.
Речь идет о приложении для распространения сообщений. Сообщения принимаются и помещаются в очередь Oracle Advanced Queues с помощью Camel. Затем они поглощаются верблюдом и перенаправляются в целевую систему. В случае сбоя доставки сообщения, в Расширенной очереди определено количество повторов, поэтому доставка сообщения повторяется.
Если Camel теперь удаляет сообщение и отправляет его в целевую систему, которая недоступна, генерируется исключение HttpOperationFailedException или NoSuchEndpointException. Они перехвачены и выполняется откат.
На этом этапе ожидается, что доставка сообщения будет повторяться так часто, как определено в счетчике повторов, а затем перемещаться в очередь исключений. Тем не менее, происходит следующее отправление следующего сообщения в очереди.
Поскольку содержимое сообщений частично зависит друг от друга, они должны обрабатываться последовательно.
Я думаю, что в использовании библиотеки JMS есть неправильная конфигурация, но я не уверен и не нашел ничего, что могло бы повлиять на это поведение.
Используемая библиотека JMS - Oracle AqApi v 11.2.0.3.
Вот код для маршрута Camel:
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 ответ
Я не эксперт по Oracle AQ, но, насколько я понимаю, это настройка в очереди, а не на стороне клиента.
Параметр sort_list определяет порядок, в котором сообщения удаляются. Вы не можете изменить порядок сортировки сообщений после того, как создали таблицу очередей.
от: http://docs.oracle.com/cd/B19306_01/server.102/b14257/aq_admin.htm
Скорее всего, вы установили ENQ_TIME или COMMIT_TIME, что может уже удовлетворить ваши потребности.
И, конечно, ваш потребитель должен быть единственным.