Upload
others
View
14
Download
0
Embed Size (px)
Citation preview
Java Message Service (JMS)
dr hab. inż. Marek Wojciechowski
Plan wykładu
• Message-Oriented Middleware
• Java Message Service (JMS)
• Message-Driven Beans
Message-Oriented Middleware (MOM)
• Infrastruktura programowa („software’owa”) umożliwiająca wysyłanie i odbiór wiadomości między komponentami systemu informatycznego w środowisku rozproszonym
– orientacja na elastyczność i współpracę heterogenicznych komponentów aplikacji
• Cechą wyróżniającą MOM od innych rozwiązań middleware jest asynchroniczna forma komunikacji
– nadawca wiadomości nie jest blokowany po jej wysłaniu
– struktura przesyłanych wiadomości zależy od aplikacji
• Historia w skrócie
– Pierwsze produkty nieoparte o standardy („proprietary”)
– JMS jako standardowe API opracowane dla aplikacji Java
– Advanced Message Queuing Protocol (AMQP): standardowy protokół dla inteoperacyjności (standard OASIS i ISO)
Implementacje MOM
• IBM MQ
• Oracle Advanced Queueing
• TIBCO Rendezvouz
• RabbitMQ
• Apache Qpid
• MSMQ
• Azure Service Bus
Czy Apache Kafka to też MOM?
JMS
AMQP
Java Message Service (JMS)
• Standard Java dla systemów wymiany wiadomości
– część Java EE
– dotyczy Enterprise Messaging (termin używany przez Sun dla MOM)
• Ułatwia implementację systemów zorientowanych na wymianę wiadomości, definiując zestaw koncepcji i strategii programistycznych z nią związanych
• Rozszerza Java EE o możliwość asynchronicznych interakcji między luźno powiązanymi komponentami Java EE i aplikacjami spadkowymi zdolnymi do wymiany wiadomości
• Opracowany jako ujednolicone API dla istniejących systemów
– później dostawcy JMS zintegrowani z serwerami aplikacji Java EE (np., GlassFish Message Queue, HornetQ => Apache ActiveMQ Artemis)
• API, a nie protokół => brak interoperacyjności
Cechy JMS
• Używa wiadomości do komunikacji między komponentami aplikacji
– zamiast bezpośrednich wywołań metod
• Umożliwia luźne powiązanie komponentów aplikacji
• Umożliwia asynchroniczną komunikację
• Wspiera dwa modele dostarczania wiadomości:
– Point-to-Point
– Publish/Subscribe
• Umożliwia komunikację wiarygodną
– domyślnie przesłane wiadomości są przechowywane w trwałym repozytorium
– domyślnie gwarancja dostarczenia wiadomości dokładnie raz (automatyczne potwierdzanie)
Komunikacja asynchroniczna w JMS
• Nadawca zawsze asynchroniczny
– po wysłaniu wiadomości nie jest blokowany
• Klienci aplikacyjni mogą odbierać wiadomości synchronicznie lub asynchronicznie
• Komponenty aplikacji Java EE:
– komponenty webowe i sesyjne EJB mogą odbierać wiadomości tylko synchronicznie
– komunikatowe EJB odbierają wiadomości asynchronicznie
Podstawowe elementy JMS
• JMS provider
• JMS destination
– JMS queue
– JMS topic
• JMS client
– JMS producer
– JMS consumer
• JMS message
Model Point-to-Point
• Komunikacja 1-do-1 (nadawca -> odbiorca)
– każda wiadomość ma jednego odbiorcę
• Odbiorca nie musi być aktywny w momencie dotarcia wiadomości
wysyła
potwierdza
konsumuje kolejka (queue)
Model Publish/Subscribe
• Komunikacja 1-do-wielu (wydawca -> subskrybenci)
– Każda wiadomość może mieć wielu odbiorców
• Rozróżnienie pojęć subskrypcja i subskrybent
• Subskrypcje: nondurable / durable, unshared / shared
• Konsument musi być aktywny aby wiadomości go nie ominęły (chyba że „durable subscription”)!
publikuje dostarcza
subskrybuje temat (topic)
dostarcza
subskrybuje
Interfejsy JMS
• ConnectionFactory (QueueConnectionFactory, TopicConnectionFactory)
• Connection (QueueConnection, TopicConnection
• Destination (Queue, Topic)
• Session (QueueSession, TopicSession)
• MessageProducer (QueueSender, TopicPublisher)
• MessageConsumer (QueueReceiver, QueueBrowser, TopicSubscriber)
[pakiet javax.jms]
Architektura aplikacji JMS
• Obiekty tworzone przez administratora, umieszczane w przestrzeni nazw JNDI serwera Java EE:
– Connection factories
– Destinations (kolejki lub tematy)
JMS provider
JMS JMS
JMS client
(consumer)
JMS client
(producer) queues / topics
jms/queue1
jms/queue2
jms/topic1
JMS 1.x: Wysyłanie wiadomości
@Resource(mappedName="jms/ConnectionFactory") private static ConnectionFactory cf; @Resource(mappedName=”jms/Queue”) private static Queue queue; Connection conn = cf.createConnection(); Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); TextMessage msg = session.createTextMessage(); msg.setText("Komunikat testowy"); producer.send(msg);
JMS 2.0 (Java EE 7)
• Uproszczenie API do wysyłania i odbierania wiadomości
• Obiekt kontekstu JMS (JMSContext)
– łączy funkcjonalność Session i Connection
• Connection = fizyczne łącze do serwera JMS
• Session = jednowątkowy kontekst do wysyłania i odbierania wiadomości
– w EE i tak tylko jedna aktywna sesja w ramach połączenia
JMS 2.0: Wysyłanie wiadomości
@Inject private JMSContext context; @Resource(mappedName=”jms/Queue”) private static Queue queue; TextMessage msg = context.createTextMessage("txt"); context.createProducer().send(queue, msg);
JMS 2.0: Synchroniczny odbiór wiadomości
• Metoda receive()
– receive()
– receive(long timeout)
• Metoda receiveNoWait()
@Inject private JMSContext context; @Resource(mappedName=”jms/Queue”) private static Queue queue; JMSConsumer consumer = context.createConsumer(queue); Message m = consumer.receive(1);
Komunikatowe komponenty EJB
• Message-driven beans (MDB)
• Bezstanowe komponenty służące jako asynchroniczni konsumenci wiadomości JMS
• Pełnią funkcję „message listener”
• Wszystkie instancje komunikatowego komponentu są równoważne
– typowo serwer utrzymuje pulę instancji w celu umożliwienia współbieżnego przetwarzania strumienia wiadomości
Cykl życia komunikatowego EJB
Nie
istnieje
Wywołania @PostConstruct Gotowy
Wstrzykiwanie zależności
Wywołania @PreDestroy
onMessage()
Struktura kodu komunikatowego EJB
• Komunikatowe EJB nie są bezpośrednio wywoływane przez klientów, więc nie posiadają interfejsów biznesowych
• Kod komunikatowego EJB stanowi jedynie klasa komponentu:
– implementująca javax.jms.MessageListener
– posiadająca implementację metody onMessage()
– oznaczona adnotacją @MessageDriven
– posiadająca publiczny bezargumentowy konstruktor
Komponent komunikatowy: Przykład
@MessageDriven(mappedName="jms/Queue") public class MyMessageBean implements MessageListener { public void onMessage(Message msg) { TextMessage txtMsg = null; try { if (msg instanceof TextMessage) { txtMsg = (TextMessage) msg; String txt = txtMsg.getText(); ... } } catch (JMSException e) {...} } }
Transakcje w JMS
• Klienci aplikacyjni
– sesję JMS można utworzyć jako transacted session
• sekwencja operacji send/receive wymaga zatwierdzenia (commit) i jest realizowana atomowo
• Aplikacje Java EE
– typowo wykorzystują transakcje JTA
• operacje JMS i np. na bazie danych w ramach jednej transakcji
• Message-driven beans
– CMT – zalecane, dostarczenie wiadomości do MDB jest częścią transakcji
– BMT – nie ma możliwości objęcia dostarczenia wiadomości transakcją (tylko przetworzenie wiadomości)