2009-09-11 6 views
4

Nous avons une application qui traite les messages JMS à l'aide d'un bean géré par message. Cette application est déployée sur un serveur d'application OC4J. (10.1.3)Assurer le traitement en série des messages JMS dans un cluster OC4J

Nous prévoyons de déployer cette application sur plusieurs serveurs d'applications OC4J qui seront configurés pour s'exécuter dans un cluster.

Le problème provient du traitement des messages JMS dans ce cluster. Nous devons veiller à ce qu'un seul message soit traité dans l'ensemble du cluster OC4J en une seule fois. Ceci est requis, car les messages doivent être traités dans l'ordre chronologique.

Connaissez-vous un paramètre de configuration qui contrôlerait le traitement des messages sur un cluster OC4J? Ou pensez-vous que nous devons implémenter notre propre code de synchronisation qui synchronisera les beans pilotés par message à travers le cluster?

+0

Les gars, merci pour vos idées sur le design. Je vous assure que le design est correct. L'objectif principal de l'application n'est pas de traiter les messages jms, la file d'attente est uniquement là pour traiter les tâches qui peuvent être effectuées en arrière-plan et ne nécessitent pas beaucoup de performances. L'exigence pour ces messages est qu'ils doivent être traités dans l'ordre dans lequel ils ont été placés, et ils ne doivent pas non plus être traités en parallèle, sinon il se produira. La question est, existe-t-il un moyen facile de configurer une application j2ee s'exécutant sur un cluster pour n'avoir qu'un seul mdb actif? –

+0

Bien sûr, vous pouvez utiliser le mécanisme de bail que j'ai décrit avec un bail unique. c'est vraiment facile, surtout s'il y a déjà une base de données quelque part. –

+0

Alors, quel est le niveau de débit dont vous avez besoin?combien de messages/seconde, par exemple? –

Répondre

5

J'ai effectué un traitement séquentiel de messages dans une grappe sur une très grande échelle - 1,5 million + message/jour, en utilisant une combinaison du modèle des consommateurs concurrents et un modèle de bail.

Voici le kicker, cependant - votre exigence que vous ne pouvez traiter qu'un trans à la fois va vous empêcher d'atteindre vos objectifs. Nous avions la même exigence de base - les messages devaient être traités dans l'ordre. Au moins, nous avons pensé que nous l'avons fait. Puis nous avons eu une révélation - comme nous avons réfléchi au problème, nous nous sommes rendu compte que nous n'avions pas besoin d'un ordre total. Nous avons réellement besoin de commander seulement dans chaque compte. Par conséquent, nous pourrions répartir la charge entre les serveurs d'un cluster en affectant des plages de comptes à différents serveurs du cluster. Ensuite, chaque serveur était responsable de traiter les messages d'un compte donné dans l'ordre.

Voici la deuxième partie intelligente: nous avons utilisé un modèle de bail pour assigner dynamiquement des plages de compte à divers serveurs du cluster. Si un serveur de la grappe tombait en panne, un autre prenait le contrat de location et prenait la responsabilité du premier serveur.

Cela a fonctionné pour nous, et le processus a vécu dans la production pendant environ 4 ans avant d'être remplacé en raison d'une fusion d'entreprise.

Edit:

J'explique cette solution plus en détail ici: http://coders-log.blogspot.com/2008/12/favorite-projects-series-installment-2.html

Edit:

D'accord, Gotcha. Vous effectuez déjà le traitement au niveau dont vous avez besoin, mais comme vous êtes déployé sur un cluster, vous devez vous assurer qu'une seule instance de votre MDB extrait activement les messages de la file d'attente. De plus, vous avez besoin de la solution la plus simple possible.

Vous n'avez pas besoin d'abandonner votre mécanisme MDB que vous avez maintenant, je ne pense pas. Essentiellement, ce dont nous parlons ici est une exigence pour un mécanisme de verrouillage distribué, pas pour mettre une phrase trop chic.

Alors, laissez-moi suggérer cela. Au point où votre MDB s'inscrit pour recevoir des messages de la file d'attente, il devrait vérifier le verrou distribué, et voir s'il peut le saisir. Le premier MDB à saisir le verrou gagne, et seulement il enregistrera pour recevoir des messages. Donc, maintenant vous avez votre sérialisation. Quelle forme doit prendre ce verrou? Il y a beaucoup de possibilités. Eh bien, qu'en penses-tu? Si vous avez accès à une base de données, son verrouillage transactionnel fournit déjà une partie de ce dont vous avez besoin. Créez une table avec une seule ligne. Dans la rangée est l'identifiant du serveur qui détient actuellement le verrou, et un délai d'expiration. C'est le bail du serveur. Chaque serveur doit avoir un moyen de générer son identifiant unique, par exemple le nom du serveur plus un identifiant de thread.

Si un serveur peut obtenir un accès de mise à jour à la ligne et que le bail a expiré, il doit le récupérer. Sinon, il abandonne. S'il saisit le bail, il doit mettre à jour la ligne avec une heure dans un proche avenir, comme cinq minutes environ, et valider la mise à jour. Le serveur actif doit mettre à jour le bail avant son expiration. Je recommande de le mettre à jour quand il reste la moitié du temps, donc toutes les 2-1/2 minutes si le bail expire dans cinq. Avec ceci, vous avez maintenant le basculement. Si le MDB actif meurt, un autre MDB (et un seul) prendra le relais.

Cela devrait être assez simple, je pense. Maintenant, vous voulez que les MDB dormantes vérifient le verrou de temps en temps pour voir si elle est libérée. Ainsi, les MDB actifs et les MDB dormants doivent tous faire quelque chose périodiquement. Vous pourriez les faire apparaître un fil séparé pour le faire. De nombreux fournisseurs de moteurs d'applications ne seront pas heureux si vous faites cela, mais ajouter un thread n'est pas un gros problème, d'autant plus qu'il passe le plus clair de son temps à dormir. Une autre option serait de lier dans le mécanisme de minuterie que de nombreux moteurs fournissent, et le faire réveiller votre MDB périodiquement pour vérifier le bail. Oh, et en passant - assurez-vous que les administrateurs du serveur emploient NTP pour garder les horloges raisonnablement synchronisées.

+0

Merci pour l'indice! Pendant que je lisais votre réponse, je me suis souvenu que nous avions complètement oublié les méthodes du cycle de vie des MDB. Je pense que nous serons en mesure de proposer un mécanisme simple qui ne dépendra que de ces méthodes pour garantir qu'un seul MDB traite les messages à travers le cluster. Nous utiliserons les mécanismes de verrouillage fournis par la base de données Oracle (dbms_lock). Quand nous avons une solution de travail, je vais poster des détails. –

+0

Cool! Heureux d'avoir pu aider. –

-1

Premier point: il s'agit d'une conception plutôt moche et vous limiterez sérieusement les performances en ne traitant qu'un seul message à la fois. Je suppose que vous êtes en cluster uniquement pour la tolérance aux pannes, car vous n'obtiendrez pas d'amélioration des performances? Utilisez-vous l'implémentation JMS par défaut avec OC4J ou une autre version? J'ai utilisé le MQ d'IBM par le passé et j'avais la possibilité de marquer une file comme exclusive, ce qui signifiait qu'un seul client pouvait s'y connecter. Cela semblerait offrir ce que vous voulez. Une alternative serait d'introduire un ID de séquence (aussi simple qu'un compteur incrémenté) et le client traitant le message vérifierait que l'ID de séquence est la prochaine valeur attendue, sinon le message remis. Cette approche nécessite que les différents clients conservent le dernier ID de séquence valide qu'ils ont vu dans un magasin de données centralisé, tel qu'une base de données.

+0

Nous utilisons une file d'attente avancée Oracle comme backend. –

-1

Je suis d'accord avec stevendick: Peut-être êtes-vous hors piste avec le design. En ce qui concerne les ID de séquence ou les approches similaires, je vous suggère d'avoir un aperçu des architectures de messagerie avec Enterprise Integration Patterns: Concevoir, créer et déployer des solutions de messagerie (par Gregor Hohpe et Bobby Woolf). C'est un livre génial, plein de modèles utiles ... Je suis sûr que les forces et le problème auquel vous faites face sont bien décrits.

Questions connexes