2015-05-15 20 views
7

Mój scenariusz to: - wysyłam wiadomość do kolejki, a gdy wiadomość zostanie zużyta, wysyłam ją do aplikacji oprogramowania pośredniego innej firmy. Jeśli ta aplikacja oprogramowania pośredniego nie działa, to wysłana wiadomość zniknęła z powodu rzutu. Nie chcę stracić tego komunikatu, jeśli aplikacja pośrednia jest wyłączona, chcę, aby była zawieszona lub czekała w kolejce. Sugerujemy, jak obsłużyć ten scenariusz?Jak przechowywać wiadomości w kolejce wiadomości JMS, jeśli wystąpił błąd po zużyciu wiadomości?

+0

Co powiesz na trwałą wiadomość od Ciebie -> trzecia strona ?, Jaki jest Twój system potwierdzenia u strony trzeciej? np. skąd wiesz, czy są na górze, nawet jeśli są na górze, nie generują błędów i nie wyświetlają Twojego msg? - Jaki masz kontrakt z firmą zewnętrzną? –

+0

Używam RESTful umowy o świadczenie usług internetowych do interakcji z aplikacją strony trzeciej. Jeśli serwer jest wyłączony, spróbuje połączyć się z parą razy, otrzymamy komunikat o błędzie awarii, lub komunikat o utracie połączenia. –

+1

Czy możliwe jest skonfigurowanie kolejki martwych liter, a następnie okresowe przenoszenie tych wiadomości z powrotem do głównej kolejki? – BretC

Odpowiedz

4

Należy utworzyć sesję tak:

Session session = connection.createSession(false, 
         Session.CLIENT_ACKNOWLEDGE); 

podczas próby dostarczenia wiadomości do aplikacji firm trzecich:

  • Jeśli to działa należy acknoledge wiadomość.

  • Jeśli jest na dole, nie należy go przekreślać, w ten sposób dostawca JMS będzie mógł dokonać jego ponownego ustalenia, a wiadomość nie zostanie utracona. message.acknowledge();

Ponadto, można spojrzeć na to: JMS AUTO_ACKNOWLEDGE when is it acknowledged?

0

Chociaż nie jest jasne, w jaki sposób zaprojektowana jest aplikacja zużywająca wiadomości, sugeruję zmodyfikowanie aplikacji konsumenckiej, aby pobierać wiadomości w ramach lokalnej transakcji i wysyłać wiadomości do aplikacji typu middleware. Jeśli wpis się powiódł, możesz zatwierdzić transakcję, która usunie komunikat z kolejki JMS. Jeśli aplikacja nie opublikuje wiadomości, możesz po prostu wycofać transakcję, która spowoduje, że komunikat pojawi się ponownie w kolejce JMS. Ta wiadomość zostanie dostarczona ponownie.

3

ten można osiągnąć przy użyciu moje uznanie sesji. W tym celu najpierw zmień swój kod producenta, aby użyć Session.AUTO_ACKNOWLEDGE. Podczas tworzenia sesji kolejki ustaw AUTO_ACKNOWLEDGE na wartość false. Oznacza to, że konsument musi uznać. Kiedy konsument wysyła potwierdzenie wiadomości, wiadomość zostanie usunięta z kolejki, w przeciwnym razie pozostanie w kolejce.

Poniżej znajduje się kod producenta.

try { 
     QueueConnectionFactory qcf = AppUtils.getQueueConnectionFactory(); 
     Queue q = AppUtils.getDestination(); 
     QueueConnection qConnection = qcf.createQueueConnection(); 
     QueueSession qSession = qConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 

     QueueSender qSender = qSession.createSender(q); 

     qConnection.start(); 
     TextMessage msg = qSession.createTextMessage("Hello"); 
     qSender.send(msg); 

     qSender.close(); 
     qConnection.close(); 

    } catch (JMSException e) { 
     // log your error to log file 
     e.printStackTrace(); 
    } 

Po stronie konsumenta trzeba zrobić to samo, utworzyć sesji kolejki z AUTO_ACKNOWLEDGE jako fałszywe.

Po zakończeniu pracy nad wiadomością możesz wysłać potwierdzenie, aby usunąć wiadomość z kolejki lub wiadomość pozostanie w kolejce.

try { 
     QueueConnectionFactory qcf = getQueueConnectionFactory(); 
     Queue q = getDestination(); 
     QueueConnection qConnection = qcf.createQueueConnection(); 
     QueueSession qSession = qConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 

     QueueReceiver qReceiver = qSession.createReceiver(q); 

     qConnection.start(); 
     Message msg = qReceiver.receive(); 

    // here send your message to third party application 
    //if your third party application is down 
     if(thirdpartyapp is down){ 
      //here you can raise an exception 
      //or just do nothing 
      // you're not sending acknowledgement here so the msg will 
      //remain in the queue 
     }else{  
      msg.acknowledge();//here youre sending ack, so msg will be deleted 
      qReceiver.close(); 
      qConnection.close(); 
     } 

    } catch (JMSException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
5

Kolejki JMS nie są magazynami wiadomości.

Jeśli masz "złą wiadomość", dla której przetwarzanie nadal się nie udaje, serwer JMS (jeśli został skonfigurowany) nieuchronnie zrzuci tę wiadomość do "Martwej kolejki wiadomości", która będzie powoli wypełniała się aż do innego procesu drenuje to.

Nie chcesz, aby w kolejce pojawiły się złe wiadomości, ponieważ mogą one potencjalnie zablokować kolejkę (wyobraź sobie, że masz 10 klientów, a 10 najważniejszych wiadomości jest zła, więc wszystkie procesy są kontynuowane złe wiadomości - zwlekanie z kolejką).

Potrzebny jest więc mechanizm do przechowywania wiadomości w specjalnym zlewni, w którym następnie mogą zostać wstrzyknięte do głównej kolejki do przetworzenia.

Kolejka martwych komunikatów nie jest tym mechanizmem (nie przechowuj wiadomości w kolejce JMS), może to być mechanizm WYSŁANIA wyjątkowych komunikatów do bardziej stałego obszaru pamięci (np. Tabela db lub coś innego).

Po przejściu można je zweryfikować (automatycznie, ręcznie, bez względu na) i albo ponownie dostarczyć, albo anulować.

Ale kluczowym punktem jest potrzebny do tego zewnętrzny mechanizm, sam serwer JMS nie jest odpowiednim miejscem dla tego rodzaju wiadomości.

+1

"Nie przechowuj wiadomości w kolejce JMS" czy możesz to wyjaśnić? Kolejka może być trwała, więc dlaczego nie przechowywać w niej? –

Powiązane problemy