2012-12-18 13 views
5

Aktualnie dodaje obsługę JMS do struktury podobnej do serwera aplikacji. JMS będzie implementowany przez HornetQ (samodzielny broker, słoiki hornetq na ścieżce klasy serwerów), ale nie ma ani JBoss, ani wiosny, ani niczego, co zapewniałoby MDB.Najlepsza praktyka przetwarzania wielowątkowych wiadomości w kolejkach JMS

Następnym krokiem jest dodanie detektora wiadomości do kolejki xa, która umożliwiłaby równoległe przetwarzanie wiadomości przychodzących. Niektóre komunikaty inicjowałyby długo działające zadania, więc podstawową ideą jest odrodzenie wątków roboczych z metody onMessage.

Podczas mojej długiej podróży przez Internet natknąłem się na this discussion, gdzie jeden z uczestników wspomniał, że nie zrobiłby tego, ale użyłby dodatkowej wewnętrznej kolejki do zadania: (jeden gwintowany) słuchacz wiadomości, po prostu chwyciłby komunikaty z kolejki wejściowej i tworzenie nowych komunikatów dla wewnętrznej kolejki, gdzie na drugim końcu tej wewnętrznej kolejki niektóre wątki robocze walczą o wiadomości przychodzące. Wiadomości przychodzące będą wtedy potwierdzane, gdy zostaną "skopiowane" do wewnętrznej kolejki (co jest dla mnie w porządku).

Niestety nie mówią dlaczego byłoby lepiej, aby nie tarło wątków roboczych od sposobu onMessage - Może dlatego, że słuchacz będzie blokować jeśli wszystkie wątki z puli są zajęte. Więc szukam plusów i minusów za projekty decyzji:

  • uruchomić wątków roboczych od metody onMessage słuchacza komunikatów
  • użyć kolejka wewnętrznego „Wysyłanie wiadomości do gwintów pracownik”

Odpowiedz

3

Ograniczenia transakcji, niezależnie od tego, czy wiele wątków (lub procesów) czytających z kolejki sprowadza się po prostu do tego, czy kolejność wiadomości jest ważna, czy nie. Oczywiście, jeśli kolejność jest ważna, to jeden wątek naturalnie utrzymuje tę kolejność, podczas gdy wiele wątków nie zapewni takiej gwarancji.

Co zwykle można znaleźć, to kolejność jest ważna, ale w całym zestawie wszystkich wiadomości. W tym scenariuszu, jeśli pojedynczy wątek nie jest wydajny, musisz usunąć te komunikaty z kolejki i ponownie umieścić w kolejce w tak krótkim czasie, ponieważ aby zachować kolejność, musisz użyć pojedynczego wątku czytającego z początkowego queue - stąd użycie jednej lub więcej wewnętrznych kolejek. Problem z tym związany polega na tym, że transakcja zostanie zamknięta, zanim wiadomości zostaną w pełni przetworzone, a zatem potrzebujesz jakiegoś magazynu tymczasowego, aby wiadomości nie zostały odrzucone, jeśli proces miałby się zakończyć, zanim przetwarzanie miało miejsce.

Jeśli, jak sugeruje twoje pytanie, nie martwisz się zbytnio upuszczaniem wiadomości, wtedy java.util.concurrent.BlockingQueue brzmi tak, jak potrzebujesz dla wewnętrznych kolejek z pojedynczym wątkiem obsługującym każdy z nich.