JMS - Un introduzione su Java Message Service

JMS - Un introduzione su Java Message Service
G.Morreale


Scopo dell'articolo è introdurre il lettore sul sistema di messagistica proposto da Sun.

JMS è un sistema di scambio messaggi, è un metodo di comunicazione tra componenti(o applicazioni) software come la mail lo è per le persone.

Un sistema basato sui messaggi offre la possibilità di comunicazioni peer-to-peer, ogni client può ricevere e spedire messaggi da e per ogni altro client.

JMS API: Sono delle API che consentono la creazione, spedizione, ricezione e lettura di messaggi.
Esse garantisco una comunicazione

  • Loosely Coupled - La correlazione tra i componenti che comunicano tra loro è molto bassa.
  • Asincrona (Il provider è in grado di consegnare i messaggi non appena arrivano, i client non devono fare alcuna richiesta per la ricezione)
  • Affidabile (JMS API garantiscono che il messaggio è consegnato, la garanzia vale per una sola volta!)

E' facile fare un analogia con le email, infatti il sistema dell'email garantisce lo scambio dei messaggi anche quando il mittente e il ricevente non sono contemporaneamente online(Asincronicità - a differenza di una chat), gli utenti possono usare client di posta differenti (outlook, thunderbird, una webmail etc.) senza obbligare il ricevente ad usare lo stesso client del mittente.

E' possibile già delineare e elementi che entrano in gioco in questa tecnologia:

  • JMS Provider - Offre funzioni di amministrazione e controllo. (Una sua implementazione è fornita con J2EE a partire dalla ver. 1.3)
  • JMS Clients - Componenti che producono e/o consumano messaggi
  • Messaggi - Oggetti che contengono informazioni che i vari clients intendono scambiare


Link di riferimento per JMS.
http://java.sun.com/products/jms/ 


Tipologie di approccio per scambio di messaggi (Il Dominio)

Esistono due tipologie di approcci per lo scambio di messaggi:

  • Point-to-Point
  • Publish/Subscribe

Nel primo ciascun messaggio è inviato ad una determinata coda, il ricevente estrae il messaggio da tale coda e notifica la coda circa tale ricezione. In questo sistema un messaggio è consumato da un solo client.


Nella seconda metodologia il mittente invia il messaggio al topic come nel primo caso, ma i riceventi saranno solo coloro che hanno sottoscritto la ricezione e solo coloro che l'hanno sottoscritta prima dell'invio del messaggio(E' un pò come l'abbonamento a Sky!!).

Quindi un messaggio può avere più client in ricezione.

immagine proveniente da: http://java.sun.com/products/jms/tutorial/1_3_1-fcs/doc/basics.html

La ricezione dei messaggio può essere

Sincrona - quando il client esplicitamente richiede il fetch del messaggio chiamando il metodo bloccante receiver
Asincrona - quando il client registra un Message Listener.

Elementi dell'infrastruttura

Come già accennato 3 elementi subentrano nell'uso del JMS:

  • JMS Provider - Offre funzioni di amministrazione e controllo. (Una sua implementazione è fornita con J2EE a partire dalla ver. 1.3)
  • JMS Clients - Componenti che producono e/o consumano messaggi
  • Messaggi - Oggetti che contengono informazioni che i vari clients intendono scambiare

Al fine di fare interagire questi 3 elementi bisogna introdurre gli Administred Object, ovvero oggetti particolari per la creazione delle connessioni e delle "destinazioni", tali oggetti sono gestiti a livello amministrativo, nel senso, è il sistemista che ne effettua la configurazione sull'application server.

(L'immagine rappresenta una scherma di configurazione delle risorse JMS: Connection Factories e Destination in Glassfish)

nota:
Attraverso il namespace JNDI però è possibile effettuare il lookup (o usare la dependency injection se possibile) per ottenere tali oggetti, quindi il sistemista predispone e il programmatore deve solo richiamare tali oggetti nei suoi client.


Tali oggetti sono due

Vediamo nello specifico le due tipologie di Administred Object:

Connection Factory

E' una factory che il client usa per creare una connessione con il provider. Come detto prima, la configurazione della connessione viene fatta in fase di amministrazione.
La connection factory nello specifico è un istanza dell'interfaccia QueueConnectionFactory oppure TopicConnectionFactory a seconda del tipo di approccio utilizzato (p2p, o publisher/subscriber)

nota:
Creata la connessione si instaura una comunicazione attraverso TCP/IP quindi è oppurtuno prestare attenzione ogni talvolta che non è più necessaria (es. il client produce il messaggio o lo consuma).


Destinations

Con la connection factory si crea il canale di comunicazione, la "destination" invece serve a indicare il target dei messaggi.

Nel caso di p2p si tratterà di una coda (queue) nel caso di publisher/subscriber le destinazioni sono chiamate topic.


Oggetti ottenuti dalla Factory:

Una volta creato il canale di comunicazione con la connection factory e istanziata la destinazione("destination") è possibile creare una sessione(QueueSession o  TopicSession)ovvero un contesto per la produzione e consumazione dei messaggi. Attraverso la sessione è possibile creare il message producer(QueueSender o TopicPublisher) ovvero l'oggetto responsabile dell'invio del messaggio verso la destinazione. 
Riguardo invece la ricezione è necessario creare un message receiver(QueueReceiver o TopicSubscriber) il receiver gestisce la ricezione attraverso il metodo bloccante receive() o attraverso la registrazione di un MessageListener (implementando l'interfaccia onMessage());
Un altro elemento su cui far cenno è il message selectors, da utilizzare nei casi in cui il client intende filtrare secondo determinati criteri i messaggi che riceve.

,
L'immagine rappresenta un infrastruttura p2p, nel caso di pub/sub l'immagine è analoga cambiano ovviamente le componenti, da sopra verso sotto(TopicConnectionFactory,TopicConnection,TopicSession, TopicPublisher, TopicSubscriber,Topic, Message è equivalente)


Messages

Il contenuto dello scambio sono proprio i messaggi, essi sono composti essenzialmente da 3 parti

  • Header - contiene i dati dei clients e dei providers al fine di garantire il corretto routing, nonchè la tipologia del messaggio, un timestamp , l'id del messaggio etc.
  • Properities(opzionale) - tale parte è compilata a favore del programmatore al fine di trasportare informazioni aggiuntive rispetto agli header.
  • Body(opzionale) - Il corpo del messaggio rappresentabile in 5 diversi formati:
    • TextMessage - in sostanza una String
    • MapMessage - Una sorta di hash table contenente un insieme di coppie chiave/valore
    • BytesMessage - Uno stream di bytes.
    • StreamMessage - Uno stream di tipi primitivi java
    • ObjectMessage - Un oggetto java che implementi l'interfaccia Serializable
    • Message - Un messaggio senza body contenente solo header e opzionalmente il campo properities.


Conclusione
In tale articolo si è cercato di introdurre i principali concetti che entrano in gioco quando si parla di JMS.




No comments: