Introduction à JMS 2e partie

Post on 25-Dec-2015

228 views 1 download

description

Annick FronESSIPrintemps 2004

Transcript of Introduction à JMS 2e partie

Printemps 2004 Annick Fron JMS 2ème partie 1

JMS (2ème partie)

Annick Fron

fron@essi.fr

Http://www.afceurope.com

Printemps 2004 Annick Fron JMS 2ème partie 2

Rappels du cours précédent

■ JMS (javax.jms) permet de communiquer par messages (non structurés : pas d'interface)

■ 2 modes d'émission : point à point, publish/subscribe■ 2 modes de réception : synchrone (receive bloquant),

asynchrone (MessageListener>>onMessage)■ En PtoP, les messages sont consommés par le

destinataire (<->TCP)■ En publish/subscribe, le subscriber doit être actif au

moment du publish (<->UDP)

Printemps 2004 Annick Fron JMS 2ème partie 3

Plan : pour une architecture robusteJMS est souvent reconnu comme une architecture de

communication fiable (à la différence du mail) avec une forte qualité de service dont :

■ Le filtrage de messages■ Les priorités, la persistance■ Durable subscribers■ Les accusés de réception : service, applicatifs■ Les transactions (pas de transactions en RMI)

Printemps 2004 Annick Fron JMS 2ème partie 4

Le filtrage de messages

Printemps 2004 Annick Fron JMS 2ème partie 5

Filtrage de messages

Filtre

Prop = 'blue'Prop = 'green'

Prop = 'yellow'

Printemps 2004 Annick Fron JMS 2ème partie 6

Filtrage des messages en PtoPCôté émetteur

message.setStringProperty("  myProp  ", " blue ");

Côté récepteurqueueReceiver = session.createReceiver(ioQueue,

"myProp = 'blue'"); // attention aux quotes

Nota : il est impossible de modifier le sélecteur du receiver après création

2 signatures possibles : createReceiver (queue)

createReceiver (queue, selector)

Où selector est une expression logique

Printemps 2004 Annick Fron JMS 2ème partie 7

Expressions logiques pour le filtrage

Propriétés typées (String, long, boolean, byte, ...)

message.setStringProperty(“propName”,”propValue”);

message.setIntProperty(“size”,10000);

Sous-ensemble de SQL92 : attention aux quotes

(Country = 'UK') OR (Country = 'US') OR (Country = 'France')

age >= 15 AND age <= 19

Printemps 2004 Annick Fron JMS 2ème partie 8

Filtrage des topics en pubsubOn peut définir des jokers sur les Topics (* pour IBM ou Sonic)

On peut filtrer sur l'arborescence

Exemples :

Tous les résultats

Sport/Football/*/Results

Toutes les équipes

Sport/Football/* (IBM)

Sport.Football.* (Sonic)

Printemps 2004 Annick Fron JMS 2ème partie 9

Qualité de service

Printemps 2004 Annick Fron JMS 2ème partie 10

Qualité de service

■ La qualité de service est à la charge du serveur JMS■ Elle varie selon les implémentations :

– IBM Websphere MQ

– Joram

– OpenJMS

– SonicMQ

– SwiftMQ

– Etc…

■ Dans la mesure où elle est implémentée, il est possible de la paramétrer au niveau du code

■ Vérifier les fonctionnalités de l'outil choisi

Printemps 2004 Annick Fron JMS 2ème partie 11

Structure d'un message

■ Entête– JMSDestination, JMSDeliveryMode, JMSMessageId,

JMSExpiration, JMSPriority, etc.

■ Propriétés– Couple <nom, valeur>

■ Corps– TextMessage, MapMessage

– StreamMessage, ObjectMessage

– BytesMessage

■ Note : le corps n'est pas structuré. Souvent XML

Printemps 2004 Annick Fron JMS 2ème partie 12

Header d'un message

Champ du header■ JMSDestination■ JMSDeliveryMode■ JMSExpiration■ JMSPriority■ JMSMessageID■ JMSTimestamp■ JMSCorrelationID■ JMSReplyTo■ JMSType■ JMSRedelivered

Défini par ■ send ou publish method■ send ou publish method■ send ou publish method■ send ou publish method■ send ou publish method■ send ou publish method■ Client■ Client■ Client■ JMS provider

Printemps 2004 Annick Fron JMS 2ème partie 13

Le header d'un message

■ Le header transporte des propriétés de service notamment la priorité, la durée de vie, le mode de livraison (persistant ou non)

■ Tous ces éléments peuvent être décrits :– globalement au niveau du MessageProducer

– de manière intermédiaire au niveau du Message

– de manière locale au moment de l'envoi

■ Toutefois, les outils implémentent l'un ou l'autre niveau mais pas forcément tous

■ Le niveau de l'envoi est le plus fin (send)

Printemps 2004 Annick Fron JMS 2ème partie 14

Niveaux de qualité de service

MessageProducer

Messagesendsend

sendMessage

send

Printemps 2004 Annick Fron JMS 2ème partie 15

Envoi d'un message

■ 2 interfaces d'envoi– sender.send(message),

– send(Message message, int deliveryMode, int priority, long timeToLive)

■ Idem publisher.publish(message)■ Idem avec JMS 1.1 unifié : producer.send(...)

Printemps 2004 Annick Fron JMS 2ème partie 16

Les priorités■ Les priorités vont de 0 (basse) à 9 (haute) : défaut 4■ Les priorités d'un message sont définies dans le

3ème argument lors d'un envoiproducer.send(message,

DeliveryMode.NON_PERSISTENT, 3, 10000);

Nota : l'API mentionne aussi

Au niveau du messagemessage.setJMSPriority(7); // pas dans Sonic

Pour tous les messages d'un producteur (sender/publisher)producer.setPriority(7);// pas dans Sonic

Printemps 2004 Annick Fron JMS 2ème partie 17

Persistance d'un message■ 2 valeurs possibles :

– DeliveryMode.NON_PERSISTENT (rare)

– DeliveryMode.PERSISTENT (défaut)

■ 2ème argument du send(resp. publish)

publisher.publish(message, DeliveryMode.NON_PERSISTENT, 3, 10000)

■ Idem précédemment pour l'API

■ MessageMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT)

■ MessageProducer

producer.setDeliveryMode(...)

Printemps 2004 Annick Fron JMS 2ème partie 18

Nota

■ Le mode de persistance est à la discrétion du serveur de messages.

■ Si le serveur tombe, les messages non persistants sont perdus, les autres sont renvoyés lors de la restauration du serveur

■ Sémantique "one only"

"A message is guaranteed to be delivered once and only once by a JMS provider if the delivery mode of the message is PERSISTENT and if the destination has a sufficient message retention policy."

Printemps 2004 Annick Fron JMS 2ème partie 19

Définition de la durée de vie d'un message■ Exprimée en ms■ 0 : le message n'expire jamais, 10000 au bout de 10s

(10000 ms) : par défaut n'expire jamais■ 4 ème argument du send

topicPublisher.publish(message, DeliveryMode.NON_PERSISTENT, 3, 10000)

■ Idem pour l'API

■ Aussi sur le producteurproducer.setTimeToLive(10000);

■ Message

Message.setJMSExpiration(10000)

Printemps 2004 Annick Fron JMS 2ème partie 20

Question

■ A quoi sert de définir la durée de vie d'un message ?

Printemps 2004 Annick Fron JMS 2ème partie 21

DurableSubscribers

Printemps 2004 Annick Fron JMS 2ème partie 22

Publish/subscribe

■ En point à point, le message est consommé par le destinataire, dans le délai de son expiration

■ En publish/subscribe, le nombre de destinataires est inconnu : impossible de déterminer qui va louper le message ni combien d'acquittements attendre !

■ Seuls les abonnés actifs à l'envoi du message le reçoivent le message

■ Nota : c'est aussi lié sans doute à UDP

Printemps 2004 Annick Fron JMS 2ème partie 23

La dure vie des abonnés

M3 - M4 pas reçus !

Printemps 2004 Annick Fron JMS 2ème partie 24

Les ''durable subscribers''

On n'a manqué aucun épisode !

Printemps 2004 Annick Fron JMS 2ème partie 25

Principe des durable subscribers

■ Les abonnés durables peuvent recevoir un topic même s'ils n'étaient pas connectés au moment de l'envoi

■ Ceci permet la fiabilité du point à point en mode publish/subscribe

■ Bien sûr au dépend des performances

Printemps 2004 Annick Fron JMS 2ème partie 26

Scénario

■ Un subscriber s'abonne à un topic■ Lorsque le publisher publie un topic, il le reçoit■ Il ne reçoit plus rien s'il quitte et relance

■ Un Durable subscriber au contraire reçoit tous les messages à la reconnection

Printemps 2004 Annick Fron JMS 2ème partie 27

Durable subscribers : principe

■ créer une ID client sur la connexion avant de l'ouvrir

conn.setClientID("maConnexion");

conn.start()

■ Envoyer le topic comme persistantproducer.send(mess,DeliveryMode.PERSISTENT,4,30000);

■ créer un abonné durable (durableSubscriber) avec une référence d'abonnement:

session.createDurableSubscriber(topic, "monAbonnement");

Printemps 2004 Annick Fron JMS 2ème partie 28

Suppression d'un abonnement

■ Fermeture de l'abonné

topicSubscriber.close();

// optionnel en Sonic

■ Suppression de l'abonnement

topicSession.unsubscribe("monAbonnement");

Printemps 2004 Annick Fron JMS 2ème partie 29

Question

■ On peut préconfigurer la ConnectionFactory avec le client ID.

■ Comment s'assurer que l'application se connecte toujours avec le même client ID ?

Printemps 2004 Annick Fron JMS 2ème partie 30

Le top de la qualité de service

■ Publish and Subscribe■ Durable Subscriptions■ Persistent Messages (DeliveryMode.PERSISTENT)■ ExceptionListener for Connection Failure■ setPingInterval sur la connection (heartbeat)

Printemps 2004 Annick Fron JMS 2ème partie 31

Résumé : durable subscribers

■ Permettent la fiabilité du point à point en mode publish/subscribe

■ Nécessitent un ID de connexion, une référence d'abonnement

Printemps 2004 Annick Fron JMS 2ème partie 32

Accusés de réception

Printemps 2004 Annick Fron JMS 2ème partie 33

Sémantique one only

Serveur

Retrait 200$

!Conn. timeout

Retrait 200$

Printemps 2004 Annick Fron JMS 2ème partie 34

En JMS

■ 2 types d'accusés de réception :■ accusé de "service" indiquant à l'infrastructure que le

message peut être supprimé ; il n'est pas vu de l'application. Ils sont liés à la durée de vie du message, à son mode de livraison (persistant ou non), et au mode d'envoi (point à point, pub/sub)

■ accusé de réception applicatif en direction de l'émetteur, programmé à la main

Printemps 2004 Annick Fron JMS 2ème partie 35

Rappel : mode point à point

Il ne peut y avoir qu'un seul consommateur.Le message est ensuite retiré après acquittement

Printemps 2004 Annick Fron JMS 2ème partie 36

Rappel : mode pub/sub

Pour les durable subscribers comme point à point , pour les autres subscribers message retiré en fin de session

Printemps 2004 Annick Fron JMS 2ème partie 37

Acknowledge

■ Pour savoir quand le message a été consommé, on utilise un acknowledge : implicite ou par programme

■ Le type d'acknowledge est associé à la Session lors de sa création

queueConnection.createQueueSession(

transacted,

Session.AUTO_ACKNOWLEDGE)

Printemps 2004 Annick Fron JMS 2ème partie 38

Question

■ Question : pourquoi la session, pas le message ?

Printemps 2004 Annick Fron JMS 2ème partie 39

Rappels Session

■ Une Session peut gérer plusieurs émetteurs/récepteurs, envois/réceptions : scénario

sess

ion

receive

send

receive

send

Printemps 2004 Annick Fron JMS 2ème partie 40

Note : connexions et sessions

Session

Session

Session

Connexion

Client

Il peut y avoir plusieurssession dans une connexionUne connexion est liée àun serveur (ex : maui)

Printemps 2004 Annick Fron JMS 2ème partie 41

Acknowledge

Printemps 2004 Annick Fron JMS 2ème partie 42

Accusés de réception de service

■ Plusieurs types d'accusés de réception :

■ Session.AUTO_ACKNOWLEDGE : accusé automatique

■ Session.CLIENT_ACKNOWLEDGE : accusé explicite■ Session.DUPS_OK_ACKNOWLEDGE : accusé

retardé, plusieurs accusés possibles

Printemps 2004 Annick Fron JMS 2ème partie 43

Différents types d'acknowledge

■ Session.AUTO_ACKNOWLEDGE :– Envoyé dès que le récepteur termine onMessage en

asynchrone, receive en synchrone

■ Session.CLIENT_ACKNOWLEDGE– L'acknowledge est global au niveau de la session (pour tous

les messages jusqu'à présent) et déclenché explicitement côté réception par :

message.acknowledge()

Printemps 2004 Annick Fron JMS 2ème partie 44

Différents types (suite)

Session.DUPS_OK_ACKNOWLEDGE■ Accusé de réception "paresseux"■ A n'utiliser que par les récepteurs qui peuvent

accepter des messages dupliqués■ Minimise le travail de la session pour éviter les

doublons■ => plus de sémantique "one only"

Printemps 2004 Annick Fron JMS 2ème partie 45

Modes d'accusés de réceptionNouveaumessage !

Tu accapares la bande

passante !

CLIENT

J'ai reçu 50 messages

jusqu'à présent

Paresseux si tu veux, mais n'importe

si je reçois 2 fois

Que fais-tu ? Je viens d'envoyer 50

messages

Tu m'obliges à envoyerles messages plusieurs

fois !

AUTO

DUPS_OK

Printemps 2004 Annick Fron JMS 2ème partie 46

Régles de retrait

■ Quand une QueueSession (ou une TopicSession avec DurableSubscribers) termine sans acknowledgement– Le serveur garde le message pour le relivrer lors de

l'ouverture de la session suivante

■ Les messages sans accusé d'un non-durable subscriber (en mode pub/sub) sont retirés lors de la fermeture de sa session

Printemps 2004 Annick Fron JMS 2ème partie 47

Session sans ack

Printemps 2004 Annick Fron JMS 2ème partie 48

Non ack recovery

Printemps 2004 Annick Fron JMS 2ème partie 49

Mode non persistant : ack OK

Printemps 2004 Annick Fron JMS 2ème partie 50

Mode non persistant : pas d'ack

Printemps 2004 Annick Fron JMS 2ème partie 51

Accusés de réception : résumé

■ Défini au niveau de la session createQueueSession(boolean transacted,

int acknowledgeMode)

3 types :■ AUTO_ACKNOWLEDGE■ CLIENT_ACKNOWLEDGE■ DUPS_OK_ACKNOWLEDGE■ Si l'acknowledge est explicite, le client doit écrire :

message.acknowledge();

Printemps 2004 Annick Fron JMS 2ème partie 52

Accusés de réception applicatifs

Printemps 2004 Annick Fron JMS 2ème partie 53

Accusés de réception applicatifs

Emet/récept A Emet/récept B

1

2

3

4

5

Est-ce que 3 est la réponse à 1 ? À 2 ?

Printemps 2004 Annick Fron JMS 2ème partie 54

Destinations temporaires

■ On peut utiliser des TemporaryQueues pour faire le lien : analogie enveloppe dans une enveloppe

■ Côté envoyeurmessage.setJMSReplyTo(session.createTemporaryQueue())

■ Côté clientproducer = session.createProducer(msg.getJMSReplyTo());

replyMsg = session.createTextMessage("Consumer " +

"processed message: " + msg.getText());

replyMsg.setJMSCorrelationID(msg.getJMSMessageID());

producer.send(replyMsg);

Les destinations temporaires n'existent que le temps de

la connexion qui les a créées

Printemps 2004 Annick Fron JMS 2ème partie 55

Destination pour la réponse

émetteur

récepteur

Printemps 2004 Annick Fron JMS 2ème partie 56

QueueRequestor

■ Il existe un framework plus systématique : QueueRequestor

Le QueueRequestor utilise 2 principes :■ la destination de réponse (TemporaryQueue définie

dans getJMSReplyTo())■ une corrélation d'ID (rappelez-vous du header !)

getJMSCorrelationID()

Printemps 2004 Annick Fron JMS 2ème partie 57

QueueRequestor : côté envoyeur

■ queueRequestor = new QueueRequestor(queueSession, queue)

■ Il n'y a pas d'envoi explicite du message, mais au contraire, attente d'une réponse :

reply = (TextMessage) queueRequestor.request(message)

■ Ceci remplace :

sender.send(message)

Printemps 2004 Annick Fron JMS 2ème partie 58

QueueRequestor : côté récepteur

■ On reçoit le message normalement : queueReceiver.receive()

■ On extrait du message une queue temporaire définie implicitement par le requestor (enveloppe de retour) :

tempQueue = (Queue) message.getJMSReplyTo();

■ On envoie un message classiquement dans cette Queue en prenant soin de fournir l'ID de corrélation :

replySender = queueSession.createSender(tempQueue);

reply = queueSession.createTextMessage(“texte mess”);

reply.setJMSCorrelationID(message.getJMSMessageID());

replySender.send(reply);

Printemps 2004 Annick Fron JMS 2ème partie 59

QueueReceptor(3) : retour à l'envoyeur■ On vérifie l'ID de corrélation du message de départ

replyID = new String(reply.getJMSCorrelationID());

messageID = message.getJMSMessageID()

replyID.equals(messageID) // oui

Printemps 2004 Annick Fron JMS 2ème partie 60

Résumé : accusés de réception applicatifs■ Il est possible d'implémenter des accusés de

réception applicatifs en utilisant des destinations temporaires

■ Le header du message transporte MessageId et MessageCorrelationID

■ Le mécanisme de QueueRequestor offre un framework plus complet et permet de s'assurer de la corrélation de deux messages en sens inverses

Printemps 2004 Annick Fron JMS 2ème partie 61

Les transactions

Printemps 2004 Annick Fron JMS 2ème partie 62

Les transactions : principe

■ Une session peut être transactionnelle■ Côté émetteur :

– Les messages envoyés ne sortent pas tant avant "commit"

– Les messages envoyés sont retirés si "rollback"

■ Côté récepteur– Les messages reçus ne sont pas acquittés avant "commit"

– Les messages reçus sont relivrés lors de "rollback"

Printemps 2004 Annick Fron JMS 2ème partie 63

Les transactions

■ La connection crée d'abord une (Q/T)session avec transaction (transacted = true):

connexion.createQueueSession(true, Session.AUTO_ACKNOWLEDGE)

■ On peut alors utiliser :

queueSession.commit();

queueSession.rollback();

Printemps 2004 Annick Fron JMS 2ème partie 64

Transaction

■ Les transactions sont consécutives

transaction1 transaction2

Commit/rollback

Il est très difficile de gérer des transactions gigognes(nested transactions)

Printemps 2004 Annick Fron JMS 2ème partie 65

Transactions locales

Printemps 2004 Annick Fron JMS 2ème partie 66

Transactions (suite)

2 clients ne peuvent partager la même transaction. Par contre un producteur peut envoyerun message à plusieurs récepteurs dans la même transaction

Printemps 2004 Annick Fron JMS 2ème partie 67

Transactions (suite)

■ On appelle toujours le rollback sur exception

catch (Exception e) {session.rollback(); …}

Printemps 2004 Annick Fron JMS 2ème partie 68

Exemple typique : cohérence d'un workflow

Service achatscommande livraison

transaction

receive send

session.createReceiver(«  commande  »);receiver.receive();session.createSender(«  livraison  »)sender.send(...)session.commit()

Printemps 2004 Annick Fron JMS 2ème partie 69

2 phases commit

■ Le 2-phase commit est une généralisation sur plusieurs transactions : pas de commit global tant que pas tous les commits individuels

■ Note : pour le two-phase commit, il est possible de compléter avec l'interface JTA/XA, mais Sun recommande d'utiliser les services propriétaires de l'implémenteur.

■ XAQueueConnectionFactory

eStore BDpaiement stockage livraison

Printemps 2004 Annick Fron JMS 2ème partie 70

Transactions : résumé

■ Une session JMS peut être transactionnelle

connexion.createQueueSession(true, 0)

■ commit et rollback concernent l'ensemble des messages de la session

■ Souvent utilisé en workflow■ Il existe des extensions JTA/XA

(XAQueueConnexionFactory) pour le 2-phase commit (Java Transaction API) y compris avec des BD

Printemps 2004 Annick Fron JMS 2ème partie 71

Conclusions

■ Le point fort de JMS est la sémantique «  one and only one  » ainsi que la qualité de service (Qos)

■ On peut définir des priorités de messages, des durées de vie de messages, la persistance

■ Les accusés de réception de service déterminent la rétention des messages

■ Il existe un framework applicatif d'accusé de réception■ JMS supporte les transactions (-> EJB et Message-

Driven Beans)

Printemps 2004 Annick Fron JMS 2ème partie 72

Références

■ http://www.hartmannsoftware.com/JMS_Tutorial.pdf■ http://www-106.ibm.com/developerworks/java/library/j-jmsvendor/?dwzone=java■ http://java.sun.com/products/jms/tutorial/