Mam problem z używaniem Apache Camel w połączeniu z kolejkami Oracle Advanced i JMS.Zużywanie wiadomości w prawidłowej kolejności z kolejki zaawansowanej przez Camel i JMS
Chodzi o aplikację do rozpowszechniania wiadomości. Wiadomości są odbierane i umieszczane w kolejkach Oracle Advanced Queues z pomocą Camel. Następnie są spożywane z Camel i przekazywane do systemu docelowego. W przypadku, gdy dostarczanie komunikatu nie powiedzie się, w kolejce zaawansowanej jest ustawiona liczba powtórzeń, aby dostarczanie wiadomości powtarza się.
Jeśli Camel odkaże wiadomość i wyśle ją do docelowego systemu, który nie jest dostępny, generowany jest wyjątek HttpOperationFailedException lub NoSuchEndpointException. Są one przechwytywane i wykonywane jest wycofywanie.
W tym momencie oczekiwanie jest takie, że dostarczenie wiadomości zostanie powtórzone tak często, jak określono w Liczniku prób, a następnie przeniesione do kolejki wyjątków. Jednak to, co się dzieje, to wysłanie kolejnej wiadomości w kolejce.
Ponieważ treść wiadomości jest częściowo zależna od siebie, muszą one być przetwarzane sekwencyjnie.
Wydaje mi się, że jest niewłaściwa konfiguracja biblioteki JMS, ale nie jestem pewien i nie znalazłem nic, co mogłoby wpłynąć na to zachowanie.
Użyta biblioteka JMS to Oracle AqApi v 11.2.0.3.
Oto kod na trasie 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();
Oto konfiguracja JmsComponent:
JmsComponent jmsComponent = new JmsComponent(scc);
jmsComponent.setConnectionFactory(connectionFactory);
jmsComponent.setTransactionManager(tm);
jmsComponent.setMaxConcurrentConsumers(1);
jmsComponent.setMaxMessagesPerTask(1);
jmsComponent.setIncludeSentJMSMessageID(true);
Z góry dziękuję za pomoc!
UPDATE
myślę, znalazłem przyczynę opisanego zachowania. W Zaawansowanej kolejce jest skonfigurowane opóźnienie. Dopóki opóźnienie trwa, kolejna wiadomość z kolejki jest usuwana. Wiadomości nie są losowane losowo, są usuwane z kolejki zgodnie z priorytetami.
Naprawdę uważam, że jest to coś, co należy skonfigurować u konsumenta. Czy istnieje jakaś sztuczka do skonfigurowania komponentu wielbłąd-jms do pobierania pierwszej wiadomości z kolejki, o ile nie została zatwierdzona lub przeniesiona do kolejki wyjątków? Nie znalazłem opcji konfiguracji bezpośrednio na wielbłądzie ...
Ogólnie w JMS kolejność komunikatów nie jest gwarantowana. W ActiveMQ, jeśli masz tylko jednego konsumenta i ponowne dostarczenie po stronie klienta, jesteś całkiem bezpieczny, ale nie wiem o Oracle AQ ... – greyfairer
Byłbym zainteresowany rozwiązaniem dla serwerów aplikacji Weblogic, jeśli istnieje nie ma uniwersalnego rozwiązania dla tego problemu. – elfwyn
Rozwiązanie (czyste) jest zawsze po stronie serwera, ponieważ klient (powinien /) nie zna wiadomości w kolejce. W zależności od QoS musisz przeczytać wszystkie wiadomości w kolejce, aby dowiedzieć się, która wiadomość ma być pierwsza - która, w zależności od opcji (konfiguracja), nadal może być opcją. Sprawdziłbym swoją odpowiedź poniżej/konfigurację po stronie serwera, zanim zaimplementujesz to po stronie klienta. HTH – PhilW