ActiveMQ: jak obsługiwać przełączanie awaryjne brokera podczas korzystania z kolejek tymczasowych

W moich aplikacjach JMS używamy tymczasowych kolejek na producentów, aby móc otrzymywać odpowiedzi z aplikacji konsumenckich.

Mam dokładnie ten sam problem z mojej strony, jak wspomniano w tym wątku: http://activemq.2283324.n4.nabble.com/jira-Created-AMQ-3336-Temporary-Destination-errors-on-H-A-failover-in-broker-network-with-Failover-tt-td3551034.html#a3612738

Gdy ponownie uruchamiałem arbitralnego brokera w mojej sieci, otrzymywałem wiele błędów, takich jak to w moim logu aplikacji konsumenckiej podczas próby wysłania odpowiedzi do tymczasowej kolejki:

javax.jms.InvalidDestinationException:
  Cannot publish to a deleted Destination: temp-queue://ID:...

Wtedy zobaczyłem odpowiedź Gary ' ego, sugerującą użycie

jms.watchTopicAdvisories=false

Jako url param na kliencie brokerURL. Szybko zmieniłem adresy URL Brokera klienta za pomocą tego dodatkowego parametru. Jednak teraz widzę takie błędy, gdy ponownie uruchamiam brokerów w sieci dla tego testu przełączania awaryjnego: {]}

javax.jms.JMSException: 
  The destination temp-queue:
    //ID:client.host-65070-1308610734958-2:1:1 does not exist.

Używam wersji ActiveMQ 5.5. A mój adres URL Brokera klienta wygląda następująco to:

failover:(tcp://amq-host1:61616,tcp://amq-host2.tred.aol.com:61616,tcp://amq-host3:61616,tcp://amq-host4:61616)?jms.useAsyncSend=true&timeout=5000&jms.watchTopicAdvisories=false
 

Dodatkowo tutaj jest mój ActiveMQ config XML dla jednego z 4 brokerów: amq1.xml

Czy ktoś tutaj może przyjrzeć się temu problemowi i zasugerować mi jaki błąd popełniam w tej konfiguracji.

Aktualizacja:

Aby wyjaśnić dalej, jak robię request-response w moim kodzie:

  1. Używam już miejsca docelowego dla producenta (tj. kolejki tymczasowej) i ustawiam to w nagłówku reply-to każdej wiadomości.
  2. już wysyłam wiadomość unikalny identyfikator korelacji w nagłówku jmscorrelationid.
  3. z tego, co wiem, nawet Camel i Spring używają tymczasowego mechanizmu kolejki odpowiedzi na żądanie. Jedyna różnica polega na tym, że implementacja Spring JMS tworzy i niszczy tymczasową kolejkę dla każdej wiadomości, podczas gdy ja tworzę tymczasową kolejkę na czas życia producenta. Ta tymczasowa kolejka jest niszczona podczas zamykania aplikacji klienta (producenta) lub przez brokera AMQ, gdy zorientuje się, że nie ma aktywnego producenta ta tymczasowa Kolejka.
  4. ustawiam już wygaśnięcie wiadomości po stronie producenta, aby wiadomość nie była zatrzymywana w kolejce zbyt długo (60 sek.).
Author: Community, 2011-06-21

2 answers

Istnieje atrybut broker, org.Apacz.activemq.broker.BrokerService#cacheTempDestinations, które powinny pomóc w przypadku przełączania awaryjnego: case. Ustaw to na true w konfiguracji xml, a miejsce docelowe tymczasowe nie zostanie usunięte natychmiast, gdy klient się rozłączy. Szybkie przełączanie awaryjne: ponowne połączenie będzie mogło ponownie produkować i / lub zużywać się z kolejki tymczasowej.

Istnieje zadanie timera oparte na timeBeforePurgeTempDestinations (domyślnie 5 sekund), które obsługuje usuwanie pamięci podręcznej.

One zastrzeżenie jednak, nie widzę żadnych testów w ActiveMQ-core, które używają tego atrybutu, więc nie mogę dać żadnej gwarancji na ten.

 27
Author: gtully,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-26 16:02:03

Tymczasowe kolejki są tworzone na brokerze, z którym łączy się zgłaszający (producent) w scenariuszu odpowiedzi na żądanie. Są one tworzone z javax.jms.Session, więc podczas rozłączenia sesji, z powodu rozłączenia klienta lub awarii brokera/przełączania awaryjnego, kolejki te znikają na stałe. Żaden z innych brokerów nie zrozumie, co oznacza, gdy jeden z Twoich konsumentów próbuje odpowiedzieć na te kolejki; stąd twój wyjątek.

Wymaga to architektonicznej zmiany sposobu myślenia, zakładając że chcesz poradzić sobie z przełączaniem awaryjnym i utrzymywać wszystkie wiadomości. Oto ogólny sposób, w jaki możesz zaatakować problem:

  1. nagłówki reply-to powinny odnosić się do kolejki specyficznej dla procesu requestora: np. queue:response.<client id>. Identyfikator klienta może być nazwą standardową, jeśli masz ograniczoną liczbę klientów, lub UUID, jeśli masz dużą ich liczbę.
  2. komunikat wychodzący powinien ustawić identyfikator korelacji (po prostu żądło, które pozwala powiązać żądanie z odpowiedzią - wnioskujący mogą jednak złożyć więcej niż jedno żądanie w tym samym czasie). Jest to ustawione w nagłówku JMSCorrelationID i powinno być skopiowane z żądania do wiadomości odpowiedzi.
  3. requestor musi ustawić listener w tej kolejce, który zwróci treść wiadomości do żądającego wątku na podstawie tego identyfikatora correllation. Istnieje kilka wielowątkowych kodów, które należy do tego napisać, ponieważ musisz ręcznie zarządzać czymś w rodzaju mapy identyfikatorów korelacji z wątkami źródłowymi (poprzez Futures być może).

Jest to podobne podejście do tego zastosowanego przezApache Camel dlarequest-response over messaging .

Należy pamiętać o tym, że kolejka nie zniknie, gdy klient to zrobi, więc powinieneś ustawić czas życia Wiadomości odpowiedzi, tak aby została usunięta z brokera, jeśli nie została zużyta, w przeciwnym razie otrzymasz zaległości z nieskonsumowanymi wiadomościami. Musisz również skonfigurować strategię kolejki martwych liter aby automatycznie usuwać wygasłe wiadomości .

 10
Author: Jakub Korab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-25 13:38:52