2015-09-16 11 views
7

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 ...

+1

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

+0

Byłbym zainteresowany rozwiązaniem dla serwerów aplikacji Weblogic, jeśli istnieje nie ma uniwersalnego rozwiązania dla tego problemu. – elfwyn

+0

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

Odpowiedz

3

Nie jestem ekspertem Oracle AQ, ale o ile widzę, jest to ustawienie w kolejce, a nie po stronie klienta .

Parametr sort_list określa kolejność odczytywania komunikatów o numerach . Nie można zmienić kolejność sortowania wiadomości po masz stworzył tabelę kolejki

od: http://docs.oracle.com/cd/B19306_01/server.102/b14257/aq_admin.htm

prawdopodobnie masz ENQ_TIME lub zestaw COMMIT_TIME - które mogą już zaspokoić swoich potrzeb.

I, oczywiście, twój konsument musi być jedyny.

+0

W moim doświadczeniu z AQ, Java jest zwykle prostą płytą kotła i rzeczywista konfiguracja dzieje się w kolejce do DB. Może również zajrzeć do grupowania wiadomości dla wiadomości zależnych http://docs.oracle.com/cd/B10501_01/appdev.920/a96587/qsample.htm#81528 – CPrescott

+0

Masz rację. Prawdziwa konfiguracja odbywa się w bazie danych. Możliwe jest skonfigurowanie opóźnienia dla kolejki, ale wydaje się, że wtedy wiadomość zostanie zablokowana tylko na czas opóźnienia, co oznacza, że ​​jms zacznie zużywać następną wiadomość. Dzięki za link, ale grupowanie wiadomości nie wydaje się rozwiązaniem, ponieważ wiadomości nie są wysyłane w tej samej transakcji. –

+0

Dziękujemy za pomoc w rozwiązaniu problemu. Naszym początkowym problemem był limit czasu ustawiony w AQ, który doprowadził do przetwarzania komunikatów kolejki poza kolejnością. Chociaż twoja wskazówka nie była zasadniczą przyczyną naszego rozwiązania, uważam, że rozsądnie jest nagradzać cię nagrodą. Dziękuję Ci! – elfwyn

Powiązane problemy